TaskCompletionSource - Пытаются понять асинхронную работу без потоков

Я пытаюсь понять цельTaskCompletionSource и его отношение к асинхронной / поточной работе. Я думаю, что у меня есть общая идея, но я хочу убедиться, что мое понимание верно.

Сначала я начал изучать Task Parallel Library (TPL), чтобы выяснить, существует ли хороший способ создать свою собственную работу без потоков или асинхронно (скажем, вы пытаетесь улучшить масштабируемость своего сайта ASP.NET), а также понять TPL. похоже это будет очень важно в будущем (async/await). Что привело меня кTaskCompletionSource.

Насколько я понимаю, это выглядит как добавлениеTaskCompletionSource для одного из ваших классов не так много, как для асинхронного кодирования; если вы все еще выполняете код синхронизации, то вызов вашего кода будет заблокирован. Я думаю, что это даже верно для API-интерфейсов Microsoft. Например, скажем вDownloadStringTaskAsync отWebClient класс, любой код установки / синхронизации, который они делают изначально, заблокирует. Код, который вы выполняете, должен запускаться в каком-то потоке, либо в текущем, либо в новом.

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

Не уверен, как Microsoft выполняет свои асинхронные API внутри. Например, есть новыйasync метод отSqlDataReader для .Net 4.5. Я знаю, что есть порты завершения ввода / вывода. Я думаю, что это абстракция более низкого уровня (C ++?), Которую, вероятно, большинство разработчиков на C # не будут использовать. Не уверен, что порты завершения ввода-вывода будут работать для базы данных или сетевых вызовов (HTTP) или если он используется только для файлового ввода-вывода.

Итак, вопрос в том, правильно ли я понимаю в своем понимании? Есть ли определенные вещи, которые я неправильно представил?

 coding4fun02 мая 2012 г., 20:43
Если мое понимание верно ... не уверен, если это так или нет
 Russ Cam02 мая 2012 г., 20:42
в чем здесь вопрос?

Ответы на вопрос(2)

Решение Вопроса

TaskCompletionSource используется для созданияTask объекты, которые не выполняют код.

Они довольно часто используются новыми асинхронными API-интерфейсами Microsoft - в любое время там, где есть асинхронные операции на основе ввода / вывода (или другие асинхронные операции не на базе процессора, например тайм-аут). Также любойasync Task Метод, который вы пишете, будет использовать TCS для завершенияTask.

У меня есть запись в блогеСоздание задач который обсуждает разные способы созданияTask экземпляров. Это написано изasync/await перспектива (не перспектива TPL), но она все еще применяется здесь.

Также см. Отличные сообщения Стивена Туба:

The Nature of TaskCompletionSource Mechanisms for Creating Tasks await anything; (using TaskCompletionSource to await anything). Using Tasks to implement the APM Pattern (creating Begin/End using TaskCompletionSource).
 03 мая 2012 г., 01:06
Любой асинхронный метод имеет (конечно) синхронную часть, которая используется для запуска асинхронной операции. IIRC, IOCP могут быть использованы для любого видаHANDLEна основе передачи данных, и нередко (сегодня) оборачивать операцию IOCP вBegin/End завернутый вasync метод, который оборачивает его вTask (с помощьюTaskCompletionSource).
 coding4fun02 мая 2012 г., 21:09
Спасибо, Стивен, но верно ли мое понимание внутренних органов?
 19 сент. 2014 г., 14:36
TaskCompletionSource логически больше событияhandler, а такжеproduces Task этот другой код можетawait, Есть два вида задач: задачи делегата и задачи обещания; я имеюa blog post that explains some of the differences.
 19 сент. 2014 г., 09:32
Я также пытаюсь понять использование TaskCompletionSource, и меня немного смущает вопрос о том, почему у вас будет задача, которая не выполняет код. Я прочитал ваш пост в блоге; кажется, что TCS используется как событие, на которое может подписаться вызывающий абонент, но зачем вам это делать, если вы можете использовать обычное задание и ждать выполнения задания, пока оно не завершится?

http://tutorials.csharp-online.net/TaskCompletionSource

(извините, ссылка может быть мертвой в данный момент)

Первые два абзаца ниже

We've seen how Task.Run creates a task that runs a delegate on a pooled (or non-pooled) thread. Another way to create a task is with TaskCompletionSource.

TaskCompletionSource lets you create a task out of any operation that starts and finishes some time later. It works by giving you a "slave" task that you manually drive—by indicating when the operation finishes or faults. This is ideal for I/O- bound work: you get all the benefits of tasks (with their ability to propagate return values, exceptions, and continuations) without blocking a thread for the duration of the operation.

To use TaskCompletionSource, you simply instantiate the class. It exposes a Task property that returns a task upon which you can wait and attach continuations—just as with any other task. The task, however, is controlled entirely by the TaskCompletionSource object via the following methods:

public class TaskCompletionSource<TResult> 
{ 
 public void SetResult(TResult result); 
 public void SetException (Exception exception); 

 public void SetCanceled();   
 public bool TrySetResult (TResult result); 
 public bool TrySetException (Exception exception); 
 public bool TrySetCanceled();
 ... 
}

Calling any of these methods signals the task, putting it into a completed, faulted, or canceled state (we'l cover the latter in the section "Cancellation"). You'e supposed to call one of these methods exactly once: if called again, SetResult, SetException, or SetCanceled will throw an exception, whereas the Try* methods return false.

The following example prints 42 after waiting for five seconds:

var tcs = new TaskCompletionSource<int>();
new Thread (() =>     {
                       Thread.Sleep (5000); 
                       tcs.SetResult (42); 
                      })    
           .Start();   
Task<int> task = tcs.Task;    // Our "slave" task. 
Console.WriteLine(task.Result);  // 42

Другие интересные цитаты

The real power of TaskCompletionSource is in creating tasks that don't tie up threads.

.. и позже

Our use of TaskCompletionSource without a thread means that a thread is engaged only when the continuation starts, five seconds later. We can demonstrate this by starting 10,000 of these operations at once without error or excessive resource consumption:

 26 дек. 2016 г., 11:52
Хорошее объяснение
 05 янв. 2015 г., 15:27
Ссылка мертва.

Ваш ответ на вопрос