简体   繁体   中英

Can I change 'Task.Run' to 'async void'? (Xamarin.forms)

I'm making app with using XF pcl. Even I launched my app on the store already, I'm still newbie in c# world. I'm having a trouble especially using a Thread.

In XF/iOS, I faced after I launched app and took a while(longer than a day), all of Task.Run() of my code does not start new thread. A person advised me if there is a chance that I'm starting many thread and somehow they are not terminated. So new thread's not started.

So I searched my project and I have Task.Run at about 20 places in my code.

I used it when I call 'async Task' method even it background thread is not necessary.

So, I'm going to change it by using 'async void'. But I already changed it like this. and no problem.

Let's say AAAAA() is a 'async Task' method from some nuget library I'm using. So I can not change method.

void Something() 
{
...
    Task.Run(async () => await XXXXX.AAAAA());
...
}

to

async void Something() 
{
...
 await XXXXX.AAAAA();
...
}

But sometimes, I faced that I can't change a method to async easily. So I'm going to change like this at that time.

void Something() 
{
...
 AA();
...
}

async void AA() 
{
await XXXXX.AAAAA();
}

Is this OK unless background thread is not necessary?

I ask this question because I watched lots of videos that saying not to use "Async void".

I wonder if I could use like this if there seems no problem.

Any advice will help me. Thanks.

Don't do async void . There are several worst practices about it.

Instead, try to solve your threading problems from the root with a good approach to asynchronous programming.

1. Define your task boundaries

Do not just "fire and forget". Expect your task to end and release resources. There are good reasons not to do Task.Run(...) and forget about it.

Async methods exist for a reason. They return in the Future (to quote the Java world). If you fire too many Async task that take long time to complete or get stuck in a loop, you drain your system resources and may end up unable to spawn new tasks.

So analyze your prolem, don't just run random methods from random packages. Design your workflow and identify parallelisms.

A simple straightforward solution is to Task.Run(()=>).Wait() . This destroys all kinds of parallelism but will constrain the resources and, most importantly, adheres with your synchronous programming.

2. A Task is not a Thread

While I discourage the unbounded/uncontrolled use of threads, the truth is that Task.Run(...) won't necessarily spawn new threads. It may not actually do anything under some circumstances.

For example I was forced to do this to force starting a new thread

Task.Factory.StartNew(()=>..., cancellationToken: tokenSource.Token, creationOptions:
                                            TaskCreationOptions.LongRunning, scheduler: TaskScheduler.Default);

TaskCreationOptions.LongRunning tells the Task factory to use an available separate thread. Normally Task.Run runs on the same current thread by exploiting VM waits to run code from other tasks, so as to perform a lightweight context switch. If your synchronous code blocks in a synchronous way the runtime may not give control to other tasks.

3. TPL is made for 2 things

One is responsiveness . If your application is completely asynchronous, then a good use of the TPL leaves your UI thread responsive over waits, eg if you click on a button you won't see the whole window greyed and "stuck". This behaviour was introduced by Microsoft to help developers that are unfriendly with proper multithread programming

The other is I/O optimization . If you need to download 5 files, parse a text file from disk and store a bunch of rows in the database you can fire 7 task that leverage the I/O wait times of each task (eg SSL handshake, disk buffering, SQL response wait) so that the 7 tasks will reasonably complete by the time of the longest.

If you just invoke asynchronous methods because you found them on your NuGet library you are just doing it wrong, as you may need to invoke the corresponding synchronous version

Summarizing

Your question reveals a lack of understanding of parallel programming. In fact you said you are new to C#. Welcome to the world of .NET.

Parallel programming is not easy, and without a knowledge of your application design it is impossible to help you in a single short answer. You need to take several examples and/or ask questions about specific best practice for some parts of your application by posting real or simil-real code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM