2010-10-03 32 views
1

如果在提示線程解決方案時沒有允許輪詢,這是什麼意思,因爲它浪費,它有延遲並且不確定。線程不應該使用輪詢來互相發信號。c#:什麼是線程輪詢?

編輯

根據您的回答,到目前爲止,我相信我的線程執行(摘自:http://www.albahari.com/threading/part2.aspx#_AutoResetEvent)以下不使用輪詢。如果我錯了,請糾正我。

using System; 
using System.Threading; 
using System.Collections.Generic; 

class ProducerConsumerQueue : IDisposable { 
    EventWaitHandle _wh = new AutoResetEvent (false); 
    Thread _worker; 
    readonly object _locker = new object(); 
    Queue<string> _tasks = new Queue<string>(); 

    public ProducerConsumerQueue() (
    _worker = new Thread (Work); 
    _worker.Start(); 
    } 

    public void EnqueueTask (string task) (
    lock (_locker) _tasks.Enqueue (task); 
    _wh.Set(); 
    } 

    public void Dispose() (
    EnqueueTask (null);  // Signal the consumer to exit. 
    _worker.Join();   // Wait for the consumer's thread to finish. 
    _wh.Close();   // Release any OS resources. 
    } 

    void Work() (
    while (true) 
    { 
     string task = null; 
     lock (_locker) 
     if (_tasks.Count > 0) 
     { 
      task = _tasks.Dequeue(); 
      if (task == null) return; 
     } 
     if (task != null) 
     { 
     Console.WriteLine ("Performing task: " + task); 
     Thread.Sleep (1000); // simulate work... 
     } 
     else 
     _wh.WaitOne();   // No more tasks - wait for a signal 
    } 
    } 
} 
+2

你的意思是池嗎? – 2010-10-03 12:29:02

+0

你需要給出更多的背景知道你在哪裏聽到這個詞,尤其是你想要達到的目標。 – 2010-10-03 12:29:17

+0

沒有沒有池 - 它是投票 – Moon 2010-10-03 12:29:54

回答

10

你的問題很不明確,但通常「輪詢」是指定期檢查一個條件或採樣一個值。例如:

while (true) 
{ 
    Task task = GetNextTask(); 
    if (task != null) 
    { 
     task.Execute(); 
    } 
    else 
    { 
     Thread.Sleep(5000); // Avoid tight-looping 
    } 
} 

只是在睡覺就是這樣做的相對低效的方式 - 它的更好,如果有一些協調,以便該線程可以喚醒時立即一些有趣的事情發生了,例如通過Monitor.Wait/PulseManual/AutoResetEvent ...但取決於上下文,這並不總是可能的。

在某些情況下,您可能不希望線程實際上睡眠 - 您可能希望它可用於其他工作。例如,您可以使用Timer這種排序或其他排序來定期輪詢郵箱以查看是否有任何傳入郵件 - 但您不需要該線程在未檢查時實際處於睡眠狀態;它可以被另一個線程池任務重用。

+0

喬恩很有用! – nawfal 2011-08-25 11:44:27

1

在這裏你去:看看這個網站:

http://msdn.microsoft.com/en-us/library/dsw9f9ts%28VS.71%29.aspx

同步技術

有兩種方法同步,輪詢和使用同步對象。輪詢重複檢查循環內異步調用的狀態。輪詢是管理線程效率最低的方式,因爲它通過反覆檢查各種線程屬性的狀態來浪費資源。

例如,在輪詢查看線程是否退出時可以使用IsAlive屬性。請謹慎使用此屬性,因爲處於活動狀態的線程不一定在運行。您可以使用線程的ThreadState屬性來獲取有關線程狀態的更多詳細信息。由於線程在任何給定時間都可以處於多個狀態,因此存儲在ThreadState中的值可以是System.Threading.Threadstate枚舉中值的組合。因此,在輪詢時應該仔細檢查所有相關的線程狀態。例如,如果線程的狀態指示它不是正在運行,則可以完成。另一方面,它可能被暫停或睡覺。 等待線程完成

Thread.Join方法對於在啓動另一個任務之前確定線程是否已完成很有用。 Join方法等待指定的時間以等待線程結束。如果線程在超時之前結束,則Join返回True;否則返回False。有關加入的信息,請參閱Thread.Join方法

輪詢犧牲了多線程的優點,以回報控制線程運行的順序。由於效率太低,通常不建議進行投票。更有效的方法將使用Join方法來控制線程。Join會導致調用過程等待直到線程完成,或者直到超時被指定時調用超時。 name,join是基於這樣的想法,即創建新線程是執行路徑中的一個分支。您可以使用加入到獨立的執行路徑合併成一個單一線程再次

有一點應該明確:加入是同步或阻塞調用。一旦你調用Join或等待句柄的等待方法,調用過程就會停止,並等待線程發信號通知它已完成。 複製

Sub JoinThreads() 
    Dim Thread1 As New System.Threading.Thread(AddressOf SomeTask) 
    Thread1.Start() 
    Thread1.Join()  ' Wait for the thread to finish. 
    MsgBox("Thread is done") 
End Sub 

控制線程,當你管理一個小數目的線程這是有用的,這些簡單的方法,是很難有大的項目中使用。下一節討論一些可用於同步線程的高級技術。

希望這會有所幫助。

PK

1

輪詢可參考用於.NET使用用於委託執行四個asyncronous圖案。

的4種類型(我已經採取了這些說明這口井解釋answer)是:

  1. 投票:在循環中,等待IAsyncResult.Completed是真實
  2. 我會打電話給你
  3. 你叫我
  4. 我不在乎會發生什麼(發射後不管)

所以對於爲例的 E:

Action<IAsyncResult> myAction = (IAsyncResult ar) => 
{ 
    // Send Nigerian Prince emails 
    Console.WriteLine("Starting task"); 
    Thread.Sleep(2000); 

    // Finished 
    Console.WriteLine("Finished task"); 

}; 

IAsyncResult result = myAction.BeginInvoke(null,null,null); 
while (!result.IsCompleted) 
{ 
    // Do something while you wait 
    Console.WriteLine("I'm waiting..."); 
} 

有投票的替代辦法,但一般它的意思是「我我們到了」,「我我們到了」,「我我們到了」

1

這是什麼意思時,一個說沒有 輪詢允許implimenting 你的線程解決方案時,因爲它是 浪費,它有延遲和它的 不確定性。線程不應該 使用輪詢來互相發信號。

我將不得不看到這個聲明的上下文,以表達對它的意見。 然而,它是明顯錯誤的。輪詢是一種非常常見且非常接受的信號線程策略。

非常多全部無鎖定線程信號傳輸策略以某種形式或其他形式使用輪詢。這清楚地表明這些策略通常在一個循環中旋轉,直到滿足特定條件。

最常用的情況是信令工作線程,現在是時候終止的情況。工作線程將定期輪詢安全點處的bool標誌,以查看是否請求了關閉。

private volatile bool shutdownRequested; 

void WorkerThread() 
{ 
    while (true) 
    { 
    // Do some work here. 

    // This is a safe point so see if a shutdown was requested. 
    if (shutdownRequested) break; 

    // Do some more work here. 
    } 
}