2017-01-13 10 views
0

次のコードでは、button1を押すと長い計算が実行され、結果がウィンドウのタイトルバーに表示されます。それは動作しますが、タスクStatusにアクセスして、タスクが正常に実行されたかどうかを確認できますか(TaskStatus.RanToCompletion)?非同期メソッドでawaitを使用する場合、どのようにタスクオブジェクトにアクセスできますか?

async private void button1_Click(object sender, EventArgs e) 
{ 
    Text = "Working"; 
    int val = await LongTask(); 
    Text = "Done: " + val; 
} 

async Task<int> LongTask() 
{ 
    return await Task.Run(() => LongFunction()); 
} 

int LongFunction() 
{ 
    Thread.Sleep(5000); 
    return 1; 
} 

答えて

3

Taskのプロパティのプロパティを使用してステータスを確認できます。しかし、async \ awaitについての素晴らしいことの1つは、これを行う必要がないということです。 awaitの場合、Task.Run(...)内の内部デリゲートからスローされた例外はすべて破棄され、同期コードであるかのようにキャッチできます。ただ

Text = "Working"; 
try { 
    int val = await LongTask(); 
    Text = "Done: " + val; 
} 
catch (Exception ex) 
{ 
    // Something went wrong 
} 
1

あなたが本当にしたい場合は可能性が

var task = SomeMethodAsync(); 
await task; 
var status = task.Status; 

しかし、あなたはawait後の行にいるならば、taskが完了しているので、それは無意味ですので、あなたは:例えば

それがすでに答えだと知っている。

例外をキャッチしてステータスを調べて、取り消しとフォールディングを区別することができますが、例外からもそれは無意味だとも言えます。

逆の場合もあります。我々が持っていると言う:

public async Task XAsync() 
{ 
    await YAsync(); 
    await ZAsync(); 
} 

今度はYAsyncが同期の復帰の高いチャンスを持っているとしましょう。その後、我々は行うことができます。このように、余分な割り当てとステート・マシンのセットアップを回避

public Task XAsync() 
{ 
    Task task = YAsync(); 
    if (task.Status == TaskStatus.RanToCompletion) 
    return ZAsync(); 
    // Do the awaiting 
    return XAsync(task); 
} 

private async Task XAsync(Task task) 
{ 
    await task; 
    await ZAsync(); 
} 

頻繁な方法を打つにはそれだけの価値、そして再びだけの価値がある、それ最初のタスクは、繰り返しのオッズは同期している場合すごく高い。また、何かがうまくいかない場合は、少し混乱する痕跡につながりますが、大きな影響を与えることがあります。

したがって、awaitより前の状態をテストすると、その使用があります。 awaitの後にテストすると、あなたがすでに知っていることが分かります。

関連する問題