0

я обнаружил, что для дорогой связанной операции ввода-вывода можно использовать TaskCompletionSourceкак реализовать метод асинхронного с помощью Task Parallel Library для операций ввода/вывода

, как показано здесь http://msdn.microsoft.com/en-us/library/hh873177.aspx#workloads

Но пример показан только ждет на некоторое время и вернуть DateTime.

public static Task<DateTimeOffset> Delay(int millisecondsTimeout) 
{ 
TaskCompletionSource<DateTimeOffset> tcs = null; 
Timer timer = null; 

timer = new Timer(delegate 
{ 
    timer.Dispose(); 
    tcs.TrySetResult(DateTimeOffset.UtcNow); 
}, null, Timeout.Infinite, Timeout.Infinite); 

tcs = new TaskCompletionSource<DateTimeOffset>(timer); 
timer.Change(millisecondsTimeout, Timeout.Infinite); 
return tcs.Task; 
} 

Выше кода ждет перерыв. У меня есть базы данных вызов, который я хочу стрелять в вышеуказанном пути, но немного путаются в том, как писать:

using (var context = new srdb_sr2_context()) 
    { 
     return context.GetData("100", "a2acfid"); 
    } 

Я написал функцию, как показано ниже, но не уверен, если это правильный способ сделать это:

TaskCompletionSource<IList<InstructorsOut>> tcs = null; 
     Timer timer = null; 

     timer = new Timer(delegate 
     { 
      timer.Dispose(); 

      //prepare for expensive data call 
      using (var context = new srdb_sr2_context()) 
      { 
       var output = context.GetData("100", "a2acfid"); 

       //set the result 
       tcs.TrySetResult(output); 
      } 

     }, null, Timeout.Infinite, Timeout.Infinite); 

     tcs = new TaskCompletionSource<IList<InstructorsOut>>(timer); 
     timer.Change(0, Timeout.Infinite); 
     return tcs.Task; 

Любая помощь будет принята с благодарностью.

+0

Причина путаницы в том, что TaskCompletionSource НЕ работает с связанными операциями ввода-вывода. Речь идет о предоставлении обертки на основе задач над другими асинхронными операциями, например. задержки таймера, события, callbakcs. Кроме того, операции с базой данных не связаны с IO. У них на самом деле очень мало ввода-вывода, пока они ждут результатов –

ответ

1

Ваш код для меня не имеет большого значения. Timer полезен, если вы хотите выполнить код через некоторое время, но это не то, что вам нужно здесь.

Если вы хотите, чтобы выполнить операцию в фоновом потоке, вы можете использовать Task.Run():

Task<IList<InstructorsOut>> GetDataBackground() 
{ 
    return Task.Run(() => 
    { 
     using (var context = new srdb_sr2_context()) 
     { 
      return context.GetData("100", "a2acfid"); 
     } 
    }); 
} 

Использование фонового потока таким образом, может быть полезным в приложениях пользовательского интерфейса, где вы не хотите, чтобы заблокировать Пользовательский интерфейс. Но если у вас есть что-то вроде приложения ASP.NET, это не даст вам каких-либо улучшений производительности или масштабируемости. Для этого метод GetData() должен быть сделан по-настоящему асинхронным.

+0

Это точно мой вопрос: как сделать GetData() действительно асинхронным. Я также добавил ссылку MSDN, которая показывает использование таймера, чтобы сделать это. –

+0

Ну, вы не можете (предполагая, что вы не можете напрямую модифицировать 'GetData()'). Автор библиотеки, содержащей 'GetData()', должен это сделать. – svick

+0

GetData() - это инфраструктура функции. Поэтому я ничего не могу сделать с тех пор, как EF 5.0 не поддерживает операции async. –

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