次のように、パラメータ付きの非同期メソッドを記述したいと思いますout
。
public async void Method1()
{
int op;
int result = await GetDataTaskAsync(out op);
}
これを でどうやって行うのですかGetDataTaskAsync
?
ベストアンサー1
ref
またはパラメータを持つ非同期メソッドは使用できませんout
。
Lucian Wischik は、この MSDN スレッドでこれが不可能な理由を説明しています。http://social.msdn.microsoft.com/Forums/en-US/d2f48a52-e35a-4948-844d-828a1a6deb74/why-async-methods-cannot-have-ref-or-out-parameters(元の投稿はリンク切れのため利用できなくなりました。最新のアーカイブ版はここにあります。
非同期メソッドが参照渡しパラメータ (または参照パラメータ) をサポートしないのはなぜでしょうか? これは CLR の制限です。私たちは、反復メソッドと同様の方法で非同期メソッドを実装することを選択しました。つまり、コンパイラがメソッドをステート マシン オブジェクトに変換する方法です。CLR には、「出力パラメータ」または「参照パラメータ」のアドレスをオブジェクトのフィールドとして安全に格納する方法がありません。参照渡しパラメータをサポートする唯一の方法は、非同期機能をコンパイラの書き換えではなく低レベルの CLR の書き換えによって実行することです。私たちはそのアプローチを検討し、多くの利点がありましたが、最終的にはコストがかかりすぎて実現しなかったでしょう。
この状況の一般的な回避策は、非同期メソッドが代わりにタプルを返すようにすることです。メソッドを次のように書き直すことができます。
public async Task Method1()
{
var tuple = await GetDataTaskAsync();
int op = tuple.Item1;
int result = tuple.Item2;
}
public async Task<Tuple<int, int>> GetDataTaskAsync()
{
//...
return new Tuple<int, int>(1, 2);
}