多線程編程學習筆記——任務並行庫(四)

来源:http://www.cnblogs.com/chillsrc/archive/2017/12/11/8023571.html
-Advertisement-
Play Games

我們學習任務調度程式,通過非同步代碼與UI進行交互。所以本示例是創建Windows應用程式。 taskScheduler是負責如何執行任務,預設情況下是把task放入線程池中的工作線程中。 ...


接上文 多線程編程學習筆記——任務並行庫(一)

接上文 多線程編程學習筆記——任務並行庫(二)

 接上文 多線程編程學習筆記——任務並行庫(三)

 

八、   並行運行任務

        本示例學習如何同時運行多個任務,並且當任務全部完成或其中一個完成時,如何高效的得到通知。

1.示例代碼

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ThreadPoolDemo
{  

    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine(" 處理並行Task。。。。。");       

                var task1 = new Task<int>(() => RunTask("任務 1", 3));     

        

                var task2 = new Task<int>(() => RunTask("任務 2", 2));
            var whenTaskAll = Task.WhenAll(task1, task2);

             whenTaskAll.ContinueWith(t => Console.WriteLine(" ——task1 結果值={0}---task2 結果值={1}",t.Result[0],t.Result[1]),
TaskContinuationOptions.OnlyOnRanToCompletion); task1.Start(); task2.Start(); Thread.Sleep(
5000); Console.WriteLine(" ——————————————————————"); var tasks = new List<Task<int>>(); for (int i = 3; i < 10; i++) { int cnt = i; var task = new Task<int>(() => RunTask(string.Format("任務 {0}",cnt), cnt)); tasks.Add(task); task.Start(); } while(tasks.Count>0) { var completedTask = Task.WhenAny(tasks).Result; tasks.Remove(completedTask); Console.WriteLine(" ——一個task 完成任務—結果值={0}", completedTask.Result); } Thread.Sleep(7000); Console.Read(); } private static int RunTask(string name,int seconds) { Console.WriteLine("Task {0} 運行線上程={1}中,是否線上程池 :{2}",name,
Thread.CurrentThread.ManagedThreadId,Thread.CurrentThread.IsThreadPoolThread); Thread.Sleep(TimeSpan.FromSeconds(seconds));
return 20 * seconds; } } }

2。程式運行結果。如下圖。

 

       當程式啟動時,創建了兩個任務(task1,task2),然後用task.whenall方法創建了第三個任務,這個任務會在所有任務完成之後運行。這個任務的結果提供了一個數組,第一個元素是第一個任務的結果,第二個元素是第二個任務的結果,以此類推。

        然後我們創建了一個任務列表,列表中有七個任務,然後使用task.whenany方法,等這一系列任務中的任何一個任務完成 ,就從列表中移除,並繼續等待其他任務完成,直到列表為空。

九、   使用taskScheduler配置任務的執行

      我們學習任務調度程式,通過非同步代碼與UI進行交互。所以本示例是創建Windows應用程式。

      taskScheduler是負責如何執行任務,預設情況下是把task放入線程池中的工作線程中。

 1.在visual studio 中創建一個windowsForm個界面,名稱為FormTPL 這個界面中有同步,非同步兩個按鈕。

 2.程式界面如下圖。

 3.代碼如下。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; 

namespace ThreadTPLDemo
{
    public partial class FormTPL : Form
    {

        public FormTPL()
        {
            InitializeComponent();

        } 

        private void buttonSync_Click(object sender, EventArgs e)
        {

            try
            {
                string result = RunTask().Result;
                textBoxMsg.Text = result;

            }
            catch (Exception ex)

            {      
          textBoxMsg.Text = ex.Message;
            }      

        } 

        private void buttonAsync_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;

            Task<string> task = RunTask();
            task.ContinueWith(t =>
            {
                textBoxMsg.Text = t.Exception.InnerException.Message;
                this.Cursor = Cursors.Arrow;
            }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted,TaskScheduler.FromCurrentSynchronizationContext());
 
        }

        private void buttonAsyncOk_Click(object sender, EventArgs e)
        {

            this.Cursor = Cursors.WaitCursor;
            Task<string> task = RunTask(TaskScheduler.FromCurrentSynchronizationContext());
            task.ContinueWith(t =>this.Cursor=Cursors.Arrow,
            CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());

        }

        private Task<string> RunTask()
        {
            return RunTask(TaskScheduler.Default);

        }
 

        private Task<string> RunTask(TaskScheduler tsched)
        {
            Task delay = Task.Delay(TimeSpan.FromSeconds(5));
            return delay.ContinueWith(t =>
            {
                string str = string.Format("Task 運行線上程={0},是否是線上程池中運行:{1}",Thread.CurrentThread.ManagedThreadId, 
Thread.CurrentThread.IsThreadPoolThread); textBoxMsg.Text
= str; return str; },tsched); } } }

 4。程式運行結果中會出現第一個問題,當點擊同步按鈕,執行程式時,整個應用 程式的用戶界面假死,無法進行其他的任務操作。如下圖。從圖中2處可以看出“非同步交互”按鈕無法顯示。

 

  5.  解決同步執行界面會假死的問題,我們使用非同步執行的方式解決。

  6. 第二個問題,而且當我們從線程中直接訪問UI界面中的控制項時,會拋出異常。

      

   7. 當我們按第三個按鈕,然後執行代碼,程式正常運行,並得到結果。如下圖。

 

 

      最後,本人不建議使用taskScheduler來開發任務調度程式,建議使用Quartz.Net來開發任務調度程式。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本篇是為項目實戰做準備,學習Linux是必備的,不然都不好意思叫全棧對吧?下麵是一位資深大神寫的文章,夠詳細,我也不用浪費時間再寫了 原文鏈接:Ubuntu學習——第一篇 內容: 一、 Ubuntu簡介 Ubuntu(烏班圖)是一個基於Debian的以桌面應用為主的Linux操作系統,據說其名稱來自 ...
  • OpenXml讀取word內容註意事項 1、使用OpenXml讀取word內容,word尾碼必須是".docx";如果word尾碼是".doc"需要轉成".docx"後,才可以讀取; 2、需要引入相關dll;"WindowsBase.dll"、“DocumentFormat.OpenXml.dll” ...
  • 一、分頁存儲過程 使用存儲過程編寫一個分頁查詢 set nocount off --關閉SqlServer消息 --set nocount on --開啟SqlServer消息 gocreate proc usp_getMyStudentsDataByPage --輸入參數@pagesize int ...
  • 有時候在窗體中執行不斷的GDI+操作的時候會出現閃速的狀況,除了修改窗體的參數,更應該解決刷新本身的問題,雙緩衝可能就是這樣來的。 方法1: 用GDI繪製在點陣圖上,然後再重新生成點陣圖 ...
  • 在上篇文章中,你跟著我寫了一個HelloWorld,本篇中,我們來談談一些C#程式中的小概念 1、C# 程式結構 一個 C# 程式主要包括以下部分: 命名空間聲明(Namespace declaration) 一個類(class) Class 方法 Class 屬性 一個 Main(主)方法 語句( ...
  • 來源:傳智播客 免費開發視頻。 問題:根據書名或出版社或作者查詢書籍信息。 知識點: 1.sql拼接 2.參數化查詢 3以下部分看起來簡單,但卻很難想到。 ...
  • 在win7,win10,vs2015,vs2017之間折騰了兩天,死活就是調不出來Mysql數據源。真是活見鬼了。 直接說方案吧。 一,卸載你所安裝過的mysql-connector-net、mysql-for-visualstudio-1.2.7、mysql-installer-community ...
  • 轉自https://www.cnblogs.com/bomo/archive/2013/02/26/2934055.html在處理較多的數據時,Bitmap中的Set/Get等函數在處理數據時比較慢,如果用記憶體法或者指針法會加快處理速度,這裡只學習了記憶體法,做一個記錄。首先我們在對Bitmap中的數... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...