为什么我的方法不是异步运行的?

时间:2014-12-31 17:56:44

标签: c# asp.net-mvc-4 asynchronous c#-5.0 async-await

我正在运行一个应该多次调用方法而不等待其结果的测试。这是我的代码:

 private async Task HandleJob(string params) {
        // do stuff that takes a minute
        Thread.Sleep(10000);
        return;
 }

 [TestMethod]
 public async Task StartTest() {
     HandleJob("one");
     HandleJob("two");
 }

当我在HandleJob("two")设置休息时,它只会在one完成后被点击。如何使它们异步运行,所以不等待?

3 个答案:

答案 0 :(得分:1)

您根本没有在方法中使用await。这意味着该方法将同步执行这些行。要实际回退给调用者并让其余代码异步运行,您需要使用await,这将继续该方法作为目标Task的延续(以及取消装箱任何异常并返回值)

Task中有几个辅助方法可以帮助解决这个问题 - 我最喜欢的是Task.Yield(),它会立即返回,因此await Task.Yield()会吐出一个新线程,一次全部归还。

[TestMethod]
public async Task StartTest() {
     await Task.Yield(); // await yields control, and Yield will ensure the rest of the method starts immediately
     HandleJob("one");
     HandleJob("two");
}

如果您希望单个子任务一次执行,请使用Task.WhenAllTask.Run

对它们进行聚合
[TestMethod]
public async Task StartTest() {
     await Task.WhenAll(
         Task.Run(() => HandleJob("one")),
         Task.Run(() => HandleJob("two")));
}

答案 1 :(得分:1)

您的异步方法HandleJob实际上不是async,因为Thread.Sleep会阻止当前线程。请尝试使用await Task.Delay。请注意,params是一个关键字,您的原始代码无法编译。我已将其更改为parameters

private async Task HandleJob(string parameters) {
        // do stuff that takes a minute
        await Task.Delay(10000);
        return;
 }

在你的start方法中,你可以返回一个Task,当两个方法在其他一个答案中指出时,使用Task.WhenAll完成这两个方法。如果您返回的结果而不是await,那么StartTest的调用者可以确定他是否等待Task完成,或者如果他忽略它并且它变成火灾并且忘记了情况。由于您未使用await StartTest,因此不再需要将其标记为async

 [TestMethod]
public Task StartTest() {
     return Task.WhenAll(HandleJob("one"), HandleJob("two"));
 }

答案 2 :(得分:0)

您需要await这两项任务:

    private void HandleJob( params string[] value )
    {
        return;
    }

    [TestMethod]
    public async Task StartTest()
    {
        var task1 = Task.Run( () => HandleJob( "one" ) );
        var task2 = Task.Run( () => HandleJob( "two" ) );
        await Task.WhenAll( task1 , task2 );
    }