尝试实现Fire并忘记:
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时犹豫不决,但想知道是否还有其他更好的方法。
目标是,我们想要"第二"尽快打印,不用担心打印的方法"首先"。火与忘记。
答案 0 :(得分:3)
实现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绑定方法。查看更多详情in this answer
另请注意,应避免在异步工作中使用同步等待。所以,改变这个:
Thread.Sleep(3000);
为此:
Task.Delay(3000);