out
次のように、パラメーターを使用して非同期メソッドを記述します。
public async void Method1()
{
int op;
int result = await GetDataTaskAsync(out op);
}
でこれを行うにはどうすればよいGetDataTaskAsync
ですか?
out
次のように、パラメーターを使用して非同期メソッドを記述します。
public async void Method1()
{
int op;
int result = await GetDataTaskAsync(out op);
}
でこれを行うにはどうすればよいGetDataTaskAsync
ですか?
ref
またはout
パラメーターを使用して非同期メソッドを使用することはできません。
Lucian Wischikは、この MSDN スレッドでこれが不可能な理由を説明しています。-ref-or-out パラメーター
非同期メソッドが out-by-reference パラメーターをサポートしていないのはなぜですか? (または参照パラメーター?) これは CLR の制限です。イテレータ メソッドと同様の方法で非同期メソッドを実装することを選択しました。つまり、メソッドをステート マシン オブジェクトに変換するコンパイラを使用します。CLR には、「出力パラメーター」または「参照パラメーター」のアドレスをオブジェクトのフィールドとして格納する安全な方法がありません。out-by-reference パラメーターをサポートする唯一の方法は、非同期機能がコンパイラーの書き換えではなく、低レベルの CLR の書き換えによって行われた場合です。私たちはそのアプローチを検討しましたが、それには多くの利点がありましたが、最終的には非常にコストがかかるため、実現することはありませんでした.
この状況の一般的な回避策は、代わりに async メソッドが Tuple を返すようにすることです。メソッドを次のように書き直すことができます。
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);
}
C#7+ の解決策は、暗黙のタプル構文を使用することです。
private async Task<(bool IsSuccess, IActionResult Result)> TryLogin(OpenIdConnectRequest request)
{
return (true, BadRequest(new OpenIdErrorResponse
{
Error = OpenIdConnectConstants.Errors.AccessDenied,
ErrorDescription = "Access token provided is not valid."
}));
}
return result は、メソッド シグネチャで定義されたプロパティ名を利用します。例えば:
var foo = await TryLogin(request);
if (foo.IsSuccess)
return foo.Result;
ref
メソッドにまたはout
パラメータを含めることはできませんasync
(前述のとおり)。
これは、動き回るデータのいくつかのモデリングを叫びます。
public class Data
{
public int Op {get; set;}
public int Result {get; set;}
}
public async void Method1()
{
Data data = await GetDataTaskAsync();
// use data.Op and data.Result from here on
}
public async Task<Data> GetDataTaskAsync()
{
var returnValue = new Data();
// Fill up returnValue
return returnValue;
}
コードをより簡単に再利用できるようになるだけでなく、変数やタプルよりもはるかに読みやすくなります。