12

私は最近初めて async (そして実際には .Net 4.5) を使用しており、困ったことに遭遇しました。私がネット上で見つけることができるクラスに関する情報はあまりないVoidTaskResultので、何が起こっているのかについて何か考えがある人がいないかどうかを確認するためにここに来ました.

私のコードは次のようなものです。明らかに、これは非常に単純化されています。基本的な考え方は、非同期のプラグイン メソッドを呼び出すことです。を返す場合Task、非同期呼び出しからの戻り値はありません。彼らが戻ってきたらTask<>、そこにあります。それらがどの型であるかは事前にわからないため、リフレクションを使用して結果の型を調べ (IsGenericType型が の場合は true Type<>)、動的型を使用して値を取得するという考え方です。

私の実際のコードでは、リフレクションを介してプラグイン メソッドを呼び出しています。これが私が見ている行動に違いをもたらすべきではないと思います。

// plugin method
public Task yada()
{
 // stuff
}

public async void doYada()
{
  Task task = yada();
  await task;

  if (task.GetType().IsGenericType)
  {
    dynamic dynTask = task;
    object result = dynTask.Result;
    // do something with result
  }
}

これは、上記のプラグイン メソッドに適しています。IsGenericTypefalse です (予想どおり)。

ただし、プラグイン メソッドの宣言をわずかに変更すると、IsGenericTypetrue が返され、処理が中断されます。

public async Task yada()
{
 // stuff
}

これを行うと、次の例外が行にスローされますobject result = dynTask.Result;

RuntimeBinderException

タスク オブジェクトを掘り下げると、実際には のように見えますType<VoidTaskResult>VoidTaskResultThreading 名前空間のプライベート タイプで、ほとんど何もありません。

VoidTaskResult タスク

呼び出しコードを変更してみました:

public async void doYada()
{
  Task task = yada();
  await task;

  if (task.GetType().IsGenericType)
  {
    object result = task.GetType().GetProperty("Result").GetMethod.Invoke(task, new object[] { });
    // do something with result
  }
}

これは、もはやスローしないという意味で「成功」しますが、今の結果は、VoidTaskResult私が賢明に何もできないタイプのものです。

これらすべてについて実際の質問を作成することさえ困難であることを付け加えておきます。多分私の本当の質問は、「何がVoidTaskResult?」または「非同期メソッドを動的に呼び出すと、なぜこの奇妙なことが起こるのですか?」のようなものです。または、「オプションで非同期のプラグイン メソッドをどのように呼び出すのですか?」いずれにせよ、教祖の一人が光を当てることができることを期待して、私はこれを公開しています.

4

1 に答える 1