简体   繁体   中英

what's the best way to invoke Async Code from Non Async in C# (Fire and Forget)

Trying to achieve Fire and Forget:

class Program
{
    static void Main(string[] args)
    {
       var my = new MyClass();

       my.OrderForm_Load();
       Console.ReadLine();
    }

}

internal class MyClass
{
    //Blocking
    public void OrderForm_Load()
    {
        var t1 = new ServiceTask();

        Task.Run(() => t1.PersistTask()); //Approach 1:
        //[OR]            
        t1.PersistTask(); //Approach 2: Has compiler errors CS4014
        Console.WriteLine("Second");
    }
}

internal class ServiceTask
{
    //Non-Blocking
    public async Task PersistTask()
    {
        var resultTask = Task.Run(() =>
        {
            Thread.Sleep(3000);
            Console.WriteLine("First");
            return Task.FromResult(0);
        });

        await resultTask;
    }
}

Between the Approach 1 and Approach 2; I prefer the Approach 1. Is there any other better way to call PersistTask() from OrderForm_Load() method? I have a colleague who is hesitant to use Task.Run but want to find out if there is any other better way.

The objective is, we want "second" to be printed ASAP and need not to worry about the method that prints "first". Fire and Forget.

The best way to achieve fire and forget methods are with the async void modifiers:

public async void PersistTask()
{
    // no need to assign the task if you are just going to await for it.
    await Task.Run(() =>
    {
        Thread.Sleep(3000);
        Console.WriteLine("First");
        return Task.FromResult(0);
    });
}

And call it using:

//Blocking
public void OrderForm_Load()
{
    var t1 = new ServiceTask();

    Task.Run(() => t1.PersistTask()); //Approach 1
    //[OR]            
    t1.PersistTask(); //Approach 2
    Console.WriteLine("Second");
}

There's another difference, though: Task.Run is best suited for CPU-bound methods. See many more details in this answer .
Also, note that you should avoid using synchronous waits in asynchronous work. So, change this:

Thread.Sleep(3000);

For this:

Task.Delay(3000);

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