4

リフレクションを使用して非同期メソッドを作成するにはどうすればよいですか?

基本的に、次のようなものが必要です。

async public Task asyncmethod()
{
   await something();
}

しかし、私は反射でそれを行う必要があります。

4

3 に答える 3

7

メソッドの変換はasyncC# (または VB.NET) コンパイラのレベルで機能し、CIL ではサポートされていません。最も単純なケースでコンパイラが行うことは、次のようなコードを変換することです。

async public Task asyncmethod()
{
    // some code
    var x = await something();
    // more code
}

基本的に次のようなものと同等のコードに変換します。

public Task asyncmethod()
{
   // some code
   return something().ContinueWith(
       t =>
       {
           var x = t.Result;
           // more code
       });
}

実際のコードはそれよりもはるかに複雑です (それは を使用し、 return already finishedSynchronizationContextの場合は実際には非同期ではなく、他のおかげでサポートしています)、より複雑な C# コードの場合はさらに複雑になります。something()TaskawaitTask

ただし、本当に Reflection.Emit を使用してメソッドを作成したい場合はasync、この変換を実際に手動で行う必要があります。

ただし、メソッドがs のawait直前に 1 回しか使用しない場合はreturn、次のように書き換えることができます ( something()a を返し、他の可能性のTaskあるものではないと仮定しますawait)。

public Task asyncmethod()
{
    // some code
    return something();
}
于 2012-06-15T09:17:14.140 に答える
1

質問を解析するもう 1 つの方法は、(たとえば、プライベート メソッドにアクセスするために) メソッド内でリフレクションを使用する必要があるが、それでも await を使用したいということです。

その場合は、通常どおりリフレクションを使用し、タスク (または待機可能なもの) を取得してから、個別に待機することができます。

何かのようなもの:

public async Task asyncmethod()
{
    Task t = ... // code that fetches the Task via reflection
    await t;
}

ただし、svick が言及しているように、await だけが最後にある場合は、メソッドを async としてマークして await を使用する代わりに、Task を返すだけです。

于 2012-06-15T09:43:28.340 に答える