我是C#的新手,想知道在哪些情况下使用Async / Await以及何时使用线程,因为我知道Async / Await不会创建新线程。
例如,如果我想在接下来的十个小时内每小时安排打印问候,应该使用以下两种打印方法中的哪一种?
private async void PrintHelloAsync(int delay)
{
await Task.Delay(delay);
Console.WriteLine("Hello");
}
private void PrintHelloThread(int delay)
{
Task.Run(async () =>
{
await Task.Delay(delay);
Console.WriteLine("Hello");
});
}
我应该在延迟增加或PrintHelloThread时调用PrintHelloAsync 10次吗?
我是否正确使用这些并发概念?
现在我正在开展一个项目,我需要在下午6点,晚上9点和午夜安排任务,并试图找出最好的方法。
答案 0 :(得分:3)
这两个函数的主要区别在于第一个函数由调用线程执行,而第二个函数由线程池中的空闲线程调用。
stackoverflow上有人用隐喻解释了我的差异(唉,我不再知道他的名字了)。
假设你想做早餐。你需要烤一些面包煮一些鸡蛋。
你可以在烤面包机里放一些面包,等到面包烤好后,从烤面包机上取下烤好的面包,然后开始加水。一旦水煮沸,你加入鸡蛋,等待一段时间,从水中取出鸡蛋,并灭火。这是同步执行的典型示例。
另一方面,将面包放入烤面包机后,您可能已经开始开水了。等到面包烤或水沸腾。在第一种情况下,您将取出面包并等待水煮沸。在后一种情况下,您将鸡蛋放入水中,等待面包烤或鸡蛋准备好。一旦你需要等待某些事情发生,你就可以看看你是否可以做其他事情来加速这个过程:一个典型的异步执行例子,但仍然由一个线程执行。这是async-await使用的方法,即第一个函数使用的方法。
最昂贵的方法是雇佣一名厨师,当你开始加热水煮一些鸡蛋时,你会点一些面包:由多个线程同时处理。
如果你有一个只有一件事要做的线程,那么如果那个线程雇用一个厨师来做这件事并让那个线程等到厨师做好准备就不明智了:为什么不让线程做那东西?
因此,如果您的主题没有其他任何操作,请使用您的第一个函数。
但是,如果您的线程本身在异步函数中运行,则只能调用此第一个函数。如果您的线程不是异步功能,并且在面包烘烤时它可以做一些有意义的事情,请考虑使用第二种方法。
答案 1 :(得分:1)
我认为最终你的目标是在下午6点,晚上9点等安排你的任务。如果不深入细节,你可能会走错路(延迟任务和思考线程)。相反,我建议您查看一个调度程序系统 - 如Quartz.net或HangFire - 托管在Windows服务中,或者只是使用Windows任务调度程序在特定时间启动您的应用程序。
如果您别无选择,只能自己实施一个调度系统,我会将System.Timers.Timer类视为一个开始:
using System;
using System.Threading.Tasks;
using System.Timers;
class Example
{
static void Main()
{
Timer timer = new Timer(1000);
timer.Elapsed += async ( sender, e ) => await HandleTimer();
timer.Start();
Console.Write("Press any key to exit... ");
Console.ReadKey();
}
private static Task HandleTimer()
{
Console.WriteLine("Timer event");
}
}