0

Предположим, у меня есть метод следующую сигнатуру метода асинхронным:Преобразовать метод Async использовать Task Parallel библиотека

public IAsyncResult MyAsyncMethod(AsyncCallback asyncCallback, object state); 

И, следовательно, я использую следующий код для вызова его и присвоить ему state объект и обратный вызов:

public class test 
{ 
    // Private class to hold/pass-through data used by Async operations 
    private class StateData 
    { 
     //... Whatever properties I'll need passed to my callback ... 
    } 

    public void RunOnSeparateThread() 
    { 
     StateData stateData = new StateData { ... }; 
     MyAsyncMethod(m_asyncCallback, stateData); 
    } 

    private AsyncCallback m_asyncCallback = new AsyncCallback(AsyncComplete); 
    private static void AsyncComplete(IAsyncResult result) 
    { 
     // Whatever stuff needs to be done after completion of Async method 
     // using data returned in the stateData object 
    } 
} 

Я ищу, чтобы сделать то же самое с помощью Task Parallel Library, и я не уверен, как это сделать. Что бы правильный код, чтобы достичь того же результата, являются:

  1. Run MyAsyncMethod в отдельном потоке
  2. По завершении есть state объект, возвращаемый с ним передается следующему методу - В этом случае AsyncComplete

Или есть лучший способ добиться того же результата?

Кроме того, хотя это написано на C#, я в равной степени удобен в VB и C#, поэтому любой ответ будет очень благодарен.

Благодарим вас и, надеюсь, это имеет смысл.

+2

Это должно помочь вам начать работу. Http://www.albahari.com/threading/part5.aspx#_Task_Parallelism –

+0

спасибо, @JoshL, выглядит очень полезная ссылка - Вглядываясь в нее сейчас. –

+0

Возможно [это на MSDN] (https://msdn.microsoft.com/en-us/library/hh191443.aspx) также хорошо. – pid

ответ

1

Предположим, что у меня есть метод следующую сигнатуру метода асинхронным:

public IAsyncResult MyAsyncMethod(AsyncCallback asyncCallback, object state); 

Я бы ожидать, что возвращаемое значение будет Task<T> (IAsyncResult обычно возвращается из BeginXYZ, когда есть соответствие EndXYZ в исходном .NET async-образце) и не принимать обратный вызов. (Как представляется, это немного один шаблон и немного другого.)

Если мое ожидание верно, просто вызовите метод и используйте перенастроенный Task<T>.

Если действительно IAsyncResult то TaskFactory имеет вспомогательный метод: FromAsync который среди его многочисленных перегрузок может принимать IAsyncResult и Action<IAsyncResult>.

Так что ваш код становится:

var ia = MyAsyncMethod(() => {}, null); 
var t = Task.Factory.FromAsync(ia, x => { 
    // called with ia from MyAsyncMethod on completion. 
    // Can close over any state 
}); 

// ... 
var result = (TypeofResult)t.Result; 
+2

't.Result' будет заблокирован. Я бы посоветовал «ждать» вместо этого, избегая также потенциальных тупиков. –

+0

@YuvalItzchakov Что касается .Net Framework ниже 4.5? С тех пор, как я не думаю, дожидается до этого. –

+1

@Josh Если вы используете .NET 4.0 и используете VS2012 и выше, у вас есть библиотека Bcl.Async через NuGet. Если вы используете .NET 4.0 и VS2010, вы можете использовать 'Task.ContinueWith' для доступа к завершенной задаче. –