溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Winform中C#線程控制的常見情況有哪些

發(fā)布時(shí)間:2021-12-03 10:11:10 來源:億速云 閱讀:124 作者:iii 欄目:編程語(yǔ)言

本篇內(nèi)容主要講解“Winform中C#線程控制的常見情況有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Winform中C#線程控制的常見情況有哪些”吧!

Winform界面中,將事務(wù)放在新開的線程中操作是十分有用的做法,因?yàn)檫@樣可以增加用戶體驗(yàn),減少耗時(shí)。對(duì)這些C#線程的控制,常常有下面這四種情況:

1. 啟動(dòng)線程;

2. 線程間通訊;

3. 線程終止;

4. 線程中的異常處理;

下面總結(jié)一些上面這些C#線程操作的常用方法。

C#線程控制1. 啟動(dòng)C#線程

◆如果是需要很頻繁的開線程,會(huì)使用線程池(微軟的或自己寫的)

◆Thread.Start(參數(shù)object);

◆或者用對(duì)象提供的BeginXXXX()這種都是異步,也算多線程啟動(dòng).

C#線程控制2. C#線程間通訊

◆委托,事件這些比較常用,并且對(duì)object的多線程處理需要謹(jǐn)慎,可能用到lock(object){}.

◆主要是通過線程同步或者回調(diào)方法(或者說是委托)來實(shí)現(xiàn)

C#線程控制3. 線程終止

◆線程的終止,用事件AUTORESET之類

◆可以用Thread.ManualEvent().Reset()/Set()/WaitOne()方法來判斷和等待

C#線程控制4. 線程中的異常處理

◆線程中的異常通過事件傳回到主線程處理

◆還是寫log吧,多線程debug比較難,還是逐步log比較好.

用于C#線程通訊的lock關(guān)鍵字

下面的示例演示使用 lock 關(guān)鍵字以及 AutoResetEvent 和 ManualResetEvent 類對(duì)主線程和兩個(gè)輔助線程進(jìn)行線程同步。

該示例創(chuàng)建兩個(gè)輔助線程。一個(gè)線程生成元素并將它們存儲(chǔ)在非線程安全的泛型隊(duì)列中。有關(guān)更多信息,請(qǐng)參見 Queue。另一個(gè)線程使用此隊(duì)列中的項(xiàng)。另外,主線程定期顯示隊(duì)列的內(nèi)容,因此該隊(duì)列被三個(gè)線程訪問。lock 關(guān)鍵字用于同步對(duì)隊(duì)列的訪問,以確保隊(duì)列的狀態(tài)沒有被破壞。

除了用 lock 關(guān)鍵字來阻止同時(shí)訪問外,還用兩個(gè)事件對(duì)象提供進(jìn)一步的同步。一個(gè)事件對(duì)象用來通知輔助線程終止,另一個(gè)事件對(duì)象由制造者線程用來在有新項(xiàng)添加到隊(duì)列中時(shí)通知使用者線程。這兩個(gè)事件對(duì)象封裝在一個(gè)名為 SyncEvents 的類中。這使事件可以輕松傳遞到表示制造者線程和使用者線程的對(duì)象。SyncEvents 類是按如下方式定義的:

C# code

using System;   using System.Threading;   using System.Collections;   using System.Collections.Generic;    public class SyncEvents   {   public SyncEvents()   {    _newItemEvent = new AutoResetEvent(false);   _exitThreadEvent = new ManualResetEvent(false);   _eventArray = new WaitHandle[2];   _eventArray[0] = _newItemEvent;   _eventArray[1] = _exitThreadEvent;   }    public EventWaitHandle ExitThreadEvent   {   get { return _exitThreadEvent; }   }   public EventWaitHandle NewItemEvent   {   get { return _newItemEvent; }   }   public WaitHandle[] EventArray   {   get { return _eventArray; }   }    private EventWaitHandle _newItemEvent;   private EventWaitHandle _exitThreadEvent;   private WaitHandle[] _eventArray;   }   public class Producer   {   public Producer(Queue <int> q, SyncEvents e)   {   _queue = q;   _syncEvents = e;   }   // Producer.ThreadRun   public void ThreadRun()   {   int count = 0;   Random r = new Random();   while (!_syncEvents.ExitThreadEvent.WaitOne(0, false))   {   lock (((ICollection)_queue).SyncRoot)   {   while (_queue.Count < 20)   {   _queue.Enqueue(r.Next(0,100));   _syncEvents.NewItemEvent.Set();   count++;   }   }   }   Console.WriteLine("Producer thread: produced {0} items", count);   }   private Queue <int> _queue;   private SyncEvents _syncEvents;   }    public class Consumer   {   public Consumer(Queue <int> q, SyncEvents e)   {   _queue = q;   _syncEvents = e;   }   // Consumer.ThreadRun   public void ThreadRun()   {   int count = 0;   while (WaitHandle.WaitAny(_syncEvents.EventArray) != 1)   {   lock (((ICollection)_queue).SyncRoot)   {   int item = _queue.Dequeue();   }   count++;   }   Console.WriteLine("Consumer Thread: consumed {0} items", count);   }   private Queue <int> _queue;   private SyncEvents _syncEvents;   }    public class ThreadSyncSample   {   private static void ShowQueueContents(Queue <int> q)   {   lock (((ICollection)q).SyncRoot)   {   foreach (int item in q)   {   Console.Write("{0} ", item);   }   }   Console.WriteLine();   }    static void Main()   {   Queue <int> queue = new Queue <int>();   SyncEvents syncEvents = new SyncEvents();    Console.WriteLine("Configuring worker threads...");   Producer producer = new Producer(queue, syncEvents);   Consumer consumer = new Consumer(queue, syncEvents);   Thread producerThread = new Thread(producer.ThreadRun);   Thread consumerThread = new Thread(consumer.ThreadRun);    Console.WriteLine("Launching producer and consumer threads...");  producerThread.Start();   consumerThread.Start();    for (int i=0; i <4; i++)   {   Thread.Sleep(2500);   ShowQueueContents(queue);   }    Console.WriteLine("Signaling threads to terminate...");   syncEvents.ExitThreadEvent.Set();    producerThread.Join();   consumerThread.Join();   }    }

到此,相信大家對(duì)“Winform中C#線程控制的常見情況有哪些”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI