是否有简单的方法来替换.Wait()以便能够异步处理它

时间:2014-10-29 12:08:42

标签: c# console-application .net-4.5

我有一个小型控制台应用程序,我有问题让应用程序在关闭之前等待所有进程完成。由于这是按计划运行的,我不能简单地添加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();
    }
}

3 个答案:

答案 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的事情,尽管它们必然会阻塞线程。

线程也非常轻巧,所以不要太担心!