Прежде всего, я объясню, что я пытаюсь сделать.
У меня есть компонент A, который использует компонент B.
Чтобы общаться между ними обоими, мне нужно использовать event.
Одним из моих предварительных условий здесь является то, чтобы компонент B работал асинхронно И запускал обработчик событий в последовательном порядке, в котором они были вызваны.
Кроме того, я хотел бы отменить трубку вызова (когда пользователь спросит об этом). Таким образом, все вызванные обработчики событий, которые еще не выполнены, никогда не будут выполняться.
Решение для достижения на является TPL. Я сделал POC того, что я пытаюсь сделать:
static void Main(string[] args)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var t = Task.Factory.StartNew(() => DoSomeWork(token));
//.ContinueWith((prevTask) => DoSomeWork(token));
t.ContinueWith((prevTask) => DoSomeWork(token));
Task.WaitAll(t);
Console.WriteLine("Finish");
Console.ReadKey();
}
static int id = 1;
static void DoSomeWork(CancellationToken ct)
{
ct.ThrowIfCancellationRequested();
Thread.Sleep(1000);
Console.WriteLine(id++);
}
Вот вывод этого фрагмента:
1
Заканчивать
2
Как видите, он заканчивается раньше, чем на самом деле. Он отображает 2 после Готово.
Если я изменю предыдущий код этим, он будет работать:
static void Main(string[] args)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var t = Task.Factory.StartNew(() => DoSomeWork(token))
.ContinueWith((prevTask) => DoSomeWork(token));
//t.ContinueWith((prevTask) => DoSomeWork(token));
Task.WaitAll(t);
Console.WriteLine("Finish");
Console.ReadKey();
}
static int id = 1;
static void DoSomeWork(CancellationToken ct)
{
ct.ThrowIfCancellationRequested();
Thread.Sleep(1000);
Console.WriteLine(id++);
}
Вот вывод этого фрагмента:
1
2
Заканчивать
Как вы понимаете, мне нужно использовать оператор continueWith не в объявлении задачи, а при возникновении события.
Почему Task.WaitAll(t); не работает первый образец?
Кто-нибудь может мне помочь?
t
содержит задачу StartNew, а во втором примереt
содержит задачу ContinueWith. Используйтеvar t1 = t.ContinueWith...; Task.WaitAll(t1);
, чтобы они вели себя одинаково - person adrianm   schedule 13.06.2016ContinueWith
наawait
и каждыйTask.Factory.StartNew
наTask.Run
. - person Stephen Cleary   schedule 13.06.2016ContinueWith
и проблемы сStartNew
. Причины связаны с ремонтопригодностью и правильностью кода, а не с производительностью. - person Stephen Cleary   schedule 13.06.2016