Task.Wait()不等待任务完成

8

我有一个控制台应用程序,希望能够按顺序启动任务。

以下是我的代码:

static void Main()
{
    string keywords = "Driving Schools,wedding services";
    List<string> kwl = keywords.Split(',').ToList();

    foreach(var kw in kwl)
    {
        Output("SEARCHING FOR: " + kw);
        Task t = new Task(() => Search(kw));
        t.Start();
        t.Wait();
    }

    Console.ReadLine();
}

static async void Search(string keyword)
{
    // code for searching
}

问题在于它不等待第一个任务完成执行。它会同时触发后续的任务。
我使用限速API,所以想一个接一个地执行任务。
为什么它不等待一个搜索完成才开始下一个搜索?

"Search" 方法使用了一些必须异步调用的方法,我最初尝试正常调用它时遇到错误,因此我尝试了这种方式,结果成功了。 - Guerrilla
还要理解这种行为是完美的,你正在等待一个包装异步方法的任务,该方法将具有一个await,它返回并且Task Wait完成,因此你不能抱怨。 - Mrinal Kamboj
1个回答

18
你的async方法只返回void,这意味着没有简单的方法等待它完成。 (你几乎总是应该避免使用async void方法。它们实际上只适用于订阅事件。)你的任务只调用Search,并且你正在等待“我已调用该方法”的完成... 它几乎立即就会完成。
如果你实际上想要按顺序执行操作,那么为什么要使用async呢?但我建议将你的代码更改为以下方式:
static void Main()
{
    // No risk of deadlock, as a console app doesn't have a synchronization context
    RunSearches().Wait();
    Console.ReadLine();
}

static async Task RunSearches()
{
    string keywords = "Driving Schools,wedding services";
    List<string> kwl = keywords.Split(',').ToList();

    foreach(var kw in kwl)
    {
        Output("SEARCHING FOR: " + kw);
        await Search(kw);
    }             
}

static async Task Search(string keyword)
{
    // code for searching
}

此外,async void 任何异常都可能终止进程,这不是 async Task 的行为。 - BRAHIM Kamel
谢谢!搜索功能使用了一些异步函数,我有点困惑如何从主方法开始启动它。我按照您的建议更新了我的代码,现在它运行得非常好!非常感谢Skeet先生。 - Guerrilla
@Jon Skeet 对于非控制台应用程序,应使用 Task.WhenAll 来映射 同步 上下文并避免 死锁 - Mrinal Kamboj
@MrinalKamboj:这取决于你具体在做什么,但通常你只需要awaitRunSearches返回的值。 - Jon Skeet
请参考这篇文章,了解如何在控制台应用程序中引入异步兼容的上下文。 - Jeroen Heier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接