2010-05-09 4 views

ответ

10

метод Расширение представляет собой обычный статический метод, с синтаксическим сахаром, чтобы вызвать его.

Так выработайте так, как бы вы сделали асинхронный метод (например, запустив задачу в нем, в .NET 4) и оттуда.

7

Чтобы какой-либо метод асинхронно, отправьте метод обратного вызова и попросите метод закрутить новый поток.

я взбитый короткий образец в .net 3.5 (возможно, Джон покажет нам 4.0 образца):

public static void Extension<T>(this T self, AsyncCallback callback) 
    { 
     var state = new State { callback = callback }; 
     System.Threading.ThreadPool.QueueUserWorkItem(ExtensionCore, callback); 
    } 

    private static void ExtensionCore(object state) 
    { 
     // do stuff with OtherStuff 
     var complete = new Complete(); 
     ((State)state).callback(complete); 
    } 

    private class State 
    { 
     public AsyncCallback callback { get; set; } 
     public object OtherStuff { get; set; } 
    } 

    public class Complete : IAsyncResult 
    { 
     public object AsyncState 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public System.Threading.WaitHandle AsyncWaitHandle 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public bool CompletedSynchronously 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public bool IsCompleted 
     { 
      get { throw new NotImplementedException(); } 
     } 
    } 
} 
+0

Благодарим вас за ответ. :) – 2010-05-09 07:39:55

2

По касательно связанной ноте Reactive Extensions for .NET предоставляет методы расширения, которые помогают с асинхронным программированием. .NET 4 также имеет Task Parallel Library (к которому Джон упомянул), который может помочь в параллелизации общих операций над коллекциями и в целом значительно упрощает распространение исключений (даже агрегирование исключений из нескольких задач), координацию между несколькими параллельными задачами, которые должны сочетать их результаты, поддержка отмены и другие сложные виды поведения.

4

Я думаю, что они пытаются это исправить. Во всяком случае, легко обойтись. Вот как это сделать:

Допустим, что метод асинхронной вы пытаетесь сделать в расширение выглядит следующим образом:

public static async Task DoAsynchronousWork(this string doWorkTo) 
{ 
    await AnotherAsyncFunctionAsync(doWorkTo); 
    await DoSomeOtherWorkAsync(doWorkTo); 
    await DoMoreWorkAsync(doWorkTo); 
} 

ВС не закатить истерику об этом, он будет компилировать просто хорошо. Однако, если вы попытаетесь позвонить "MyString".DoAsynchronousWork(), он выкинет ошибку, заявив, что ей не указан параметр строки. Поэтому он не полностью игнорирует тот факт, что он является расширением, но он по-прежнему требует «этого» параметра!

К счастью, это легко обойти. Просто замените DoAsynchronousWork с этим:

public static Task DoAsynchronousWork(this string doWorkTo) 
{ 
    return new Task(async() => { 
     await AnotherAsyncFunctionAsync(doWorkTo); 
     await DoSomeOtherWorkAsync(doWorkTo); 
     await DoMoreWorkAsync(doWorkTo); 
    }); 
} 

Я надеюсь, что они получают это фиксированное, прежде чем они выпускают .NET 4.5, но если нет, то, по крайней мере, это легко обойти. (Я обнаружил, что lambdas может быть асинхронным случайно, но теперь он идет очень удобно!)

+0

Спасибо, @ aboveyou00 за ценный ответ. Упростите от меня :-) Просто быстрое обновление для других исследователей; «они» сделали * получить * этот недостаток, установленный вовремя для .NET 4.5, см., например, асинхронные методы расширения в [WindowsRuntimeStorageExtensions] (http://msdn.microsoft.com/en-us/library/hh582101.aspx) класс. –

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