VS2012 を取得し、ハンドルを取得しようとしていasync
ます。
ブロッキング ソースから何らかの値を取得するメソッドがあるとします。メソッドの呼び出し元をブロックしたくありません。値が到着したときに呼び出されるコールバックを取得するメソッドを作成することもできますが、C# 5 を使用しているため、呼び出し元がコールバックを処理する必要がないようにメソッドを非同期にすることにしました。
// contrived example (edited in response to Servy's comment)
public static Task<string> PromptForStringAsync(string prompt)
{
return Task.Factory.StartNew(() => {
Console.Write(prompt);
return Console.ReadLine();
});
}
これを呼び出すメソッドの例を次に示します。非同期でない場合PromptForStringAsync
、このメソッドはコールバック内にコールバックをネストする必要があります。async を使用すると、次のように非常に自然な方法でメソッドを記述できます。
public static async Task GetNameAsync()
{
string firstname = await PromptForStringAsync("Enter your first name: ");
Console.WriteLine("Welcome {0}.", firstname);
string lastname = await PromptForStringAsync("Enter your last name: ");
Console.WriteLine("Name saved as '{0} {1}'.", firstname, lastname);
}
ここまでは順調ですね。問題は、GetNameAsyncを呼び出すときです。
public static void DoStuff()
{
GetNameAsync();
MainWorkOfApplicationIDontWantBlocked();
}
要点GetNameAsync
は、非同期であるということです。できるだけ早く MainWorkOfApplicationIDontWantBlocked に戻り、GetNameAsync にバックグラウンドで実行させたいので、ブロックしたくありません。ただし、この方法で呼び出すと、次のGetNameAsync
行でコンパイラの警告が表示されます。
Warning 1 Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
「呼び出しが完了する前に現在のメソッドの実行が続行される」ことを完全に認識しています。それが非同期コードのポイントですよね?
私は自分のコードを警告なしでコンパイルすることを好みますが、コードは意図した通りに動作しているため、ここで「修正」するものは何もありません。の戻り値を保存することで、警告を取り除くことができますGetNameAsync
。
public static void DoStuff()
{
var result = GetNameAsync(); // supress warning
MainWorkOfApplicationIDontWantBlocked();
}
しかし、今は余分なコードがあります。Visual Studio は、通常の "value never used" 警告を抑制するため、この不要なコードを書くことを余儀なくされたことを理解しているようです。
非同期ではないメソッドで GetNameAsync をラップすることで、警告を取り除くこともできます。
public static Task GetNameWrapper()
{
return GetNameAsync();
}
しかし、それはさらに余計なコードです。そのため、不要なコードを記述したり、不必要な警告を許容したりしなければなりません。
ここで間違っている async の使用について何かありますか?