2012-06-15 3 views
3

Как создать асинхронный метод с использованием отражения?Асинхронное программирование с отражением

В принципе мне нужно что-то вроде этого:

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

, но мне нужно сделать это с отражением.

+0

Зачем использовать async/wait? Если something() возвращает задачу, просто вызовите Wait. –

+2

@PanagiotisKanavos Потому что это сделало бы метод синхронным, избегая этого, это целая точка 'async'. – svick

+0

Вы не можете создавать методы отражением, вы можете назвать их –

ответ

6

Перевод методов async работает на уровне компилятора C# (или 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 
     }); 
} 

Реальный код гораздо более сложным, что это (он использует SynchronizationContext, на самом деле это не асинхронно, если something() возвращает уже готовые Task, он поддерживает await другие вещи, спасибо Task s), и это будет еще сложнее для более сложного кода C#.

Но если вы действительно хотите создать методы async, используя Reflection.Emit, это преобразование - это то, что вам действительно нужно делать вручную.

Но одна вещь, следует отметить, что если ваш метод использует await только один раз прямо перед ним return с, вы можете записать его в (при условии, something() Возвращает Task и не что-то другое, что await умеет):

public Task asyncmethod() 
{ 
    // some code 
    return something(); 
} 
+0

Не могли бы вы сказать, где я могу найти больше о том, как компилятор переводит код с помощью async?Я хотел бы ожидать чего-то другого, кроме Task, даже если код будет более сложным. – mertin

+1

Я не уверен, что существует один окончательный источник, описывающий текущую ситуацию. Лучшим вариантом будет C# 5.0 spec, но это еще не выпущено. Существует [спецификация 'async'] (http://www.microsoft.com/en-us/download/details.aspx?id=23753), [серия статей Эрика Липперта] (http: // blogs.msdn.com/b/ericlippert/archive/tags/c_2300_+5-0/) и [еще одна серия статей Джона Скита] (http://msmvps.com/blogs/jon_skeet/archive/tags/async/ default.aspx). – svick

+0

Но большинство из них говорит о CTP, и ситуация изменилась с тех пор. Хотя в частях 18 и 20 серии Джона Скита рассказывается об изменениях между CTP и DP и между DP и бета-версиями, соответственно. – svick

1

Другой способ проанализировать ваш вопрос состоит в том, что вам нужно использовать отражение внутри метода (например, для доступа к частному методу), но все же хотите использовать ожидание.

Если это так, вы можете просто использовать отражение, как обычно, вернуть задачу (или любую другую ожидаемую вещь), а затем ждать ее отдельно.

Что-то вроде:

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

хотя, как svick упоминает, если только Await в конце, просто вернуть задачу вместо маркировки метод асинхр и использование Await.

 Смежные вопросы

  • Нет связанных вопросов^_^