簡體   English   中英

在C#中從非異步調用異步代碼的最佳方法是什么(Fire和Forget)

[英]what's the best way to invoke Async Code from Non Async in C# (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;
    }
}

方法1和方法2之間; 我更喜歡方法1.還有其他更好的方法從OrderForm_Load()方法調用PersistTask()嗎? 我有一位同事在使用Task.Run時猶豫不決,但想知道是否還有其他更好的方法。

目標是,我們希望盡快打印“秒”並且不必擔心打印“第一”的方法。 火和忘記。

實現fire and forget方法的最佳方法是使用async void修飾符:

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);
    });
}

並使用以下方式調用:

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

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

但是還有另一個區別: Task.Run最適合CPU綁定方法。 在這個答案中查看更多細節。
另請注意,應避免在異步工作中使用同步等待。 所以,改變這個:

Thread.Sleep(3000);

為了這:

Task.Delay(3000);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM