Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Тема: Task Parallel Library Крыжановский Анатолий
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Одного потока хватит всем?
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Варианты многопоточности System.Threading.ThreadSystem.Threading.ThreadPool System.ComponentModel. BackgroundWorker System.Threading.Tasks.Task
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Препарируем TPL – создание задачи void SomeWork() { } Task.Run(() => SomeWork()) var task = new Task(() => SomeWork()); task2.Start(); var taskFactory = new TaskFactory(); var task = taskFactory.StartNew(() => SomeWork()); var task = Task.Factory.StartNew(() => SomeWork());
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Цепочки задач int SomeWork(int id) { var duration = (int)Math.Round(new Random(id).NextDouble() * 3 + 1); Thread.Sleep(duration * 1000); Console.WriteLine("Work {0} done in {1} seconds", id, duration); return id; } var task = Task.Run (() => SomeWork(1)).ContinueWith(t => Console.WriteLine(t.Result)); var tasks = Enumerable.Range(0, 5).Select(x => Task.Run(() => SomeWork(x))).ToArray(); Task.WhenAll(tasks).ContinueWith(t => Console.WriteLine("all task done")); var tasks = Enumerable.Range(0, 5).Select(x => Task.Run(() => SomeWork(x))).ToArray(); Task.WhenAny(tasks).ContinueWith(t => Console.WriteLine("any task done"));
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Тонкая настройка Console.WriteLine("Begin"); var task = new Task(() => { Console.WriteLine("Begin parent task"); var child = new Task(() => { Console.WriteLine("Begin child task"); Thread.Sleep(2000); Console.WriteLine("End child task"); }); child.Start(); Console.WriteLine("End parent task"); }); task.Start(); task.Wait(); Console.WriteLine("End"); Console.WriteLine("Begin"); var task = new Task(() => { Console.WriteLine("Begin parent task"); var child = new Task(() => { Console.WriteLine("Begin child task"); Thread.Sleep(2000); Console.WriteLine("End child task"); }, TaskCreationOptions.AttachedToParent); child.Start(); Console.WriteLine("End parent task"); }); task.Start(); task.Wait(); Console.WriteLine("End"); IsCompletedIsCanceledIsFaulted truefalse NotOnFaulted, NotOnCanceled, OnlyOnRanToCompletion falsetruefalseNotOnRanToCompletion, NotOnFaulted, OnlyOnCanceled false trueNotOnRanToCompletion, NotOnCanceled, OnlyOnFaulted
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Подождите, подождите!!! var tasks = Enumerable.Range(0, 5).Select(x => Task.Run(() => SomeWork(x))).ToArray(); Task.WaitAll(tasks); var tasks = Enumerable.Range(0, 5).Select(x => Task.Run(() => SomeWork(x))).ToArray(); Task.WaitAny(tasks, 1); var task = Task.Run(() => SomeWork(0)); task.Wait(); var task = Task.Run(() => SomeWork(0)); var result = task.Result; int SomeWork(int id) { var duration = (int)Math.Round(new Random(id).NextDouble() * 3 + 1); Thread.Sleep(duration * 1000); Console.WriteLine("Work {0} done in {1} seconds", id, duration); return id; }
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Отмена задачи void Work() { for (var i = 0; i < 10; i++) { Thread.Sleep(1000); Console.WriteLine("Iteration {0} done", i); } void Work(CancellationToken token) { for (var i = 0; i < 10; i++) { if(token.IsCancellationRequested) return; Thread.Sleep(1000); Console.WriteLine("Iteration {0} done", i); } void Work(CancellationToken token) { for (var i = 0; i < 10; i++) { if(token.IsCancellationRequested) throw new Exception("cancelled"); Thread.Sleep(1000); Console.WriteLine("Iteration {0} done", i); } var task = Task.Run(() => Work()).ContinueWith(t => HandleResult(t)); var cancellationSource = new CancellationTokenSource(); var task = Task.Run(() => Work(cancellationSource.Token), cancellationSource.Token).ContinueWith(t => HandleResult(t)); void Work(CancellationToken token) { for (var i = 0; i < 10; i++) { token.ThrowIfCancellRequested(); Thread.Sleep(1000); Console.WriteLine("Iteration {0} done", i); }
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Оживляем UI var task = new Task (() => DoCalculation()); task.ContinueWith(t => ShowResult(t.Result)); task.Start(); var task = new Task (() => DoCalculation()); task.ContinueWith(t => { if(InvokeRequired) Invoke(new Action(() => ShowResult(t.Result))); else ShowResult(t.Result); }); task.Start(); var task = new Task (() => DoCalculation()); task.ContinueWith(t => ShowResult(t.Result), TaskScheduler.FromCurrentSynchronizationContext()); task.Start();
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Оживляем UI Task.Factory.StartNew(() => Calc()).ContinueWith((t) => calc.Text = "Go!", TaskScheduler.FromCurrentSynchronizationContext()); private void Calc() { for (int i = 0; i < 10; i++) { Thread.Sleep(1000); var updateUiTask = updateUiTask = Task.Factory.StartNew(() => Update(i), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); updateUiTask.Wait(); } var context = TaskScheduler.FromCurrentSynchronizationContext(); Task.Factory.StartNew(() => Calc(context)).ContinueWith((t) => calc.Text = "Go!", context); private void Calc(TaskScheduler scheduler) { for (int i = 0; i < 10; i++) { Thread.Sleep(1000); var updateUiTask = Task.Factory.StartNew(() => Update(i), CancellationToken.None, TaskCreationOptions.None, scheduler); updateUiTask.Wait(); }
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Плюшки private async void goButton_Click(object sender, EventArgs e) { try { status.Text = "Download data..."; var data = await GetData(url.Text); status.Text = "Processing data..."; var processedData = await DataHandler(data); status.Text = "Done"; result.Text = processedData; } catch (Exception ex) { status.Text = ex.Message; } Task GetData(string url) { return Task.Factory.StartNew(() => { var result = new WebClient().DownloadString(url); return result; }); } Task DataHandler(string data) { return Task.Factory.StartNew(() => { Thread.Sleep(5000); var arr = data.ToCharArray(); Array.Reverse(arr); return new string(arr); }); } var syncContext = TaskScheduler.FromCurrentSynchronizationContext(); status.Text = "Download data..."; var t1 = GetData(url.Text); var t2 = t1.ContinueWith(t => { status.Text = "Processing data..."; return t.Result; }, syncContext); var t3 = t2.ContinueWith(t => { var t4 = DataHandler(t.Result); var t5 = t4.ContinueWith(p => { status.Text = "Done"; result.Text = p.Result; }, syncContext); });
Образец заголовка Образец текста –Второй уровень Третий уровень –Четвертый уровень »Пятый уровень Что почитать?