C# 多線程參數傳遞

來源:互聯網
上載者:User
1、通過實體類來傳遞(可以傳遞多個參數與擷取傳回值),demo如下:

需要線上程中調用的函數:

namespace ThreadParameterDemo{    public class FunctionClass    {        public static string TestFunction(string name, int age)        {            //內部處理省略            return name + " 的年齡是:" + age;        }    }}

通過實體來來封裝:

namespace ThreadParameterDemo{    /// <summary>    /// 過渡類    /// </summary>    public class TransitionalClass    {        private string name = string.Empty;        private int age;        public string acceptResults = string.Empty;        public TransitionalClass(string name, int age)        {            this.name = name;            this.age = age;        }        public void TestFunction()        {            acceptResults = FunctionClass.TestFunction(this.name, this.age);        }    }}

調用:

  private void Form1_Load(object sender, EventArgs e)        {            //執行個體化ThreadWithState類,為線程提供參數              TransitionalClass tc = new TransitionalClass(" Jack", 42);            // 建立執行任務的線程,並執行              Thread t = new Thread(new ThreadStart(tc.TestFunction));            t.Start();            //擷取傳回值,通過 tc.acceptResults;          }


小註:

必須注意IsBackground的問題,如果IsBackground為false的,則Windows程式在退出的時候,不會為你自動結束該線程。也就是實際上你的應用程式未結束。

MSDN推薦:多線程方法調用提供參數的最好辦法是將目標方法包裹在類中,並為該類定義欄位,這些欄位將被用作新線程的參數。

這種方法的優點是,任何時候想要啟動新線程,都可以建立類的新執行個體,該執行個體帶有自身的參數。

BackgroundWorker 類

ThreadStart中的函數是沒有傳回值和參數的

2、非同步呼叫中的參數和傳回值
能完美解決參數和傳回值的是使用非同步呼叫的方式。非同步呼叫和Thread相比,一個最大的劣勢是不能控制其優先順序。

具體代碼如下:

        public delegate string delegateFunction(string name,int age);//委託        delegateFunction df;        private void Form1_Load(object sender, EventArgs e)        {            //指向需要調用的方法            df = new delegateFunction(FunctionClass.TestFunction);            string name = "my name";//輸入參數             int age = 19;            IAsyncResult result = df.BeginInvoke(name,age, null, null);            string myResult = df.EndInvoke(result);//用於接收傳回值             MessageBox.Show(myResult);        }

簡化:

 public Func<string, int, string>  df;//委託        private void Form1_Load(object sender, EventArgs e)        {            //指向需要調用的方法            df += FunctionClass.TestFunction;            string name = "my name";//輸入參數             int age = 19;            IAsyncResult result = df.BeginInvoke(name, age, null, null);            string myResult = df.EndInvoke(result);//用於接收傳回值             MessageBox.Show(myResult);        }

小註:

通過這種方式產生新線程是運行在背景(background),優先順序為normal


3、使用 BackgroundWorker

多線程傳回值最簡單方法是:使用 BackgroundWorker 組件來管理線程,在任務完成時引發事件,然後用事件處理常式處理結果。

小註:
BackgroundWorker 組件用來執行諸如資料庫事務、檔案下載等耗時的非同步作業。
在應用程式中添加一個BackgroundWorker執行個體,如果用的是VS,可以從工具上直接拖到應用程式:

BackgroundWorker backgroundWorker1 = new BackgroundWorker();

為了開始在後台操作,必須調用BackgroundWorker的RunWorkerAsync()方法,當調用此方時,BackgroundWorker 通過觸發DoWork 事件,開始執行後台操作,DoWork 事件的代碼是在另一個線程裡執行的。
當後台操作完成以後,無論是completed 還是cancelled,則RunWorkerCompleted 事件被觸發,通過此方法可以將後台操作的完成結果反饋給使用者。
另外,通過RunWorkerCompletedEventArgs執行個體的Cancelled 屬性,以判斷是否是Cancel操作使得後台操作終止。


具體demo如下:


using System;using System.Windows.Forms;namespace WindowsFormsApplication1{    public partial class Form2 : Form    {        public Form2()        {            InitializeComponent();        }        private void Form2_Load(object sender, EventArgs e)        {            //TransitionalClass tc = new TransitionalClass("xiaoming", 10);            //ThreadPool.QueueUserWorkItem(new WaitCallback(TransitionalClass.TestFunction), tc);        }        private void button1_Click(object sender, EventArgs e)        {            this.TestArea2();        }        private System.ComponentModel.BackgroundWorker BackgroundWorker1    = new System.ComponentModel.BackgroundWorker();        private void TestArea2()        {            InitializeBackgroundWorker();            AreaClass2 AreaObject2 = new AreaClass2();            AreaObject2.Base = 30;            AreaObject2.Height = 40;            // Start the asynchronous operation.            BackgroundWorker1.RunWorkerAsync(AreaObject2);        }        private void InitializeBackgroundWorker()        {            // Attach event handlers to the BackgroundWorker object.            BackgroundWorker1.DoWork +=                new System.ComponentModel.DoWorkEventHandler(BackgroundWorker1_DoWork);            BackgroundWorker1.RunWorkerCompleted +=                new System.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker1_RunWorkerCompleted);        }        private void BackgroundWorker1_DoWork(            object sender,            System.ComponentModel.DoWorkEventArgs e)        {          //在執行DoWork 事件時,DoWorkEventArgs 執行個體的Result 屬性,傳回值到使用者;在RunWorkerCompleted 事件裡,RunWorkerCompletedEventArgs 執行個體的Result 屬性接收值;            AreaClass2 AreaObject2 = (AreaClass2)e.Argument;            // Return the value through the Result property.            e.Result = AreaObject2.CalcArea();        }        private void BackgroundWorker1_RunWorkerCompleted(            object sender,            System.ComponentModel.RunWorkerCompletedEventArgs e)        {            // Access the result through the Result property.             double Area = (double)e.Result;            MessageBox.Show("The area is: " + Area.ToString());        }    }}


demo代碼來自MSDN:點擊開啟連結


參考文章:點擊開啟連結

4、如果不如傳回值的時候,應該怎麼優雅的寫呢?匿名函數啊

FunctionClass類新增,測試函數如下:

   public static void TestFunction2(string name, int age)        {            //內部處理省略                    }

調用如下:

 private void Form1_Load(object sender, EventArgs e)        {            Thread t1 = new Thread(new ThreadStart(delegate            {                FunctionClass.TestFunction2("eee", 5);            }));            t1.Start();                  }

小註:

如果通過WCF來調用的話,應該把起線程的函數放到服務端,如果放到用戶端,很容易因為WCF用戶端的時間限制,造成造成主程式的莫名崩潰。

崩潰的原因主要是用戶端wcf回應時間是有限制。

以上就是C# 多線程參數傳遞的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.