我有一个小型控制台应用程序,我有问题让应用程序在关闭之前等待所有进程完成。由于这是按计划运行的,我不能简单地添加Console.ReadKey
或类似的东西。
调用我的第一个Async方法时,我不得不添加.Wait();
以阻止应用继续执行其余代码。我试图了解这是否可以在控制台应用程序中执行此操作,或者是否有更好的方法(希望很简单)以确保应用程序在关闭之前等待异步方法。此外,我希望能够减少应用程序消耗的资源量,并且我理解.Wait()
将占用该线程而不是释放它,这将导致额外的资源使用。
以下是我的逻辑布局。
private static List<string> taskList = new List<string>();
private static SemaphoreSlim mutex = new SemaphoreSlim(3);
private static void Main(string[] args)
{
StartAllTasks().Wait(); // This LINE
}
private static async Task StartAllTasks()
{
await Task.WhenAll(taskList.Select(name => ProcessSingleTask(name)));
}
private async static Task ProcessSingleTask(string name)
{
await mutex.WaitAsync();
try
{
TaskManager singleTask = new TaskManager(name);
await Task.Factory.StartNew(() => singleTask.ProcessTask());
}
finally
{
mutex.Release();
}
}
答案 0 :(得分:1)
不,你拥有的是最佳方式(在此上下文中)。实际上,这是在Task
方法中等待Main
的推荐方法。主要方法不能是async
,因此您不能在主要内部await
。
其他常见选项正在等待WaitHandle
,直到有人说是时候关机,这与你的实际情况完全相同。所以坚持下去。
如果你在谈论其他方法,那就是另一个故事了。但对于Main
来说,这是完全没问题的。
答案 1 :(得分:1)
Wait
中可以接受 Main
。它会&#34;浪费&#34;一个线程,但浪费一个线程通常不是一件大事。
如果它困扰你,你可以使用AsyncContext
from my AsyncEx library实际上为async
代码提供单线程上下文。它也不会在AggregateException
中包装异常。但是,这意味着您的async
代码不会在线程池线程上执行 - 它将全部在单个控制台主线程上执行。
答案 2 :(得分:0)
你所做的看起来是正确的。您需要调用Wait()来阻止主线程,因为这样可以使程序保持活动状态。阻止线程并不意味着占用太多资源。
wait和await调用没有做任何损害CPU的事情,尽管它们必然会阻塞线程。
线程也非常轻巧,所以不要太担心!