2016-12-14 12 views
1

ASP.NET Web APIアクション内の非同期タスクで少し失われています。私はアクションを持っている:タスクが終了するまでアクションから復帰しない

[HttpPost] 
public async Task<HttpResponseMessage> Restart() 
{ 
    await AspManager.Restart(); 

    return Request.CreateResponse(HttpStatusCode.OK, new { result = "Success", message = "IIS site successfully restarted" }); 
} 

再起動は、長時間実行することができ、私はそれを待ってから、応答を返すようにしたいです。その後、私は、サービスを停止し、5秒待ってからサービスを開始する必要があり、メインRestart方法でそう

public static async Task<Task> Restart() 
{ 
    var client = new Client("..."); 
    CheckApiKey(client); 

    var task = Task.Factory.StartNew(async() => 
    { 
     client.Stop(); 

     await Task.Delay(5 * 1000); 

     throw new BusinessException("test"); 
     client.Start(); 
    }); 

    return await task; 
} 

私はキーをチェックしています:ここで実行時間の長いコードです。この作業が完了するまで、コントローラからの操作は戻ってはなりません。しかし、問題はアクションが復帰し、5秒後にBusinessExceptionがスローされるということです。

+1

タスクに新しい例外がスローされています。なぜあなたは他の何かを期待していますか? – RandomStranger

+0

Hmmm、そのスローはテスト用です。私が説明した問題は、クライアントが停止して起動してからhttp応答を返すまで待つ必要があることです。しかし、ここでは最初にそれが返され、例外がスローされます。 –

答えて

2

あなたの方法はasync Task<Task>です。あなたはタスクを開始し、それを返しています。これは、タスクが開始されたばかりの状態に戻ることを意味します。

重要な点:あなたはタスクの作成を待っていますが、その実行は待ちません。

は、 await Task.Factory.StartNew(() => versus Task.Start; await Task;から、それから、 "非同期無効" であるためにあなたのメソッドのシグネチャを変更 Task.Run()を使用

public async Task Restart() 
{ 
    // ... 

    await Task.Run(async() => 
    { 
     client.Stop(); 

     await Task.Delay(5 * 1000); 

     client.Start(); 
    }); 
} 
+0

あなたは私のヒーローです:)ありがとう! –

0

Task.Factory.StartNew is a dangerous APIを、私は私のブログで説明して。実行している問題は、asyncラムダを理解できないということです。 (他にも問題があります)。

ただし、Task.Runを使用することは適切な解決策ではありません。それはASP.NETで逆効果です。 awaitを単独で使用してください:

public static async Task<Task> RestartAsync() 
{ 
    var client = new Client("..."); 
    if (CheckApiKey(client)) 
    return; 

    client.Stop(); 
    await Task.Delay(TimeSpan.FromSeconds(5)); 
    client.Start(); 
} 
関連する問題