2010-10-22 81 views
3

如果我有一個線程的問題:關於多線程

Thread sendMessage = new Thread(new ThreadStart(timer.Start())); 

意志,計時器的Tick事件將在主線程或在SendMessage線程?

編輯: 我有一個隊列,我想,每x milisecond定時器將蜱和程序將出列從隊列陣列,但是這是我的代碼:

Thread sendMessage = new Thread(new ThreadStart(startThreadTimer)); 
      public Queue<Array> messageQueue = new Queue<Array>(); 
System.Threading.Timer timer; 
      private void startThreadTimer() 
      { 
       System.Threading.TimerCallback cb = new System.Threading.TimerCallback(checkIfQueue); 
       timer = new System.Threading.Timer(cb, null, 4000, 30); 
      } 
      private static void checkIfQueue(object obj) 
      { 

      } 

可以和我「T調用無靜態方法或從checkIfQueue使用無靜電場,它必須是靜態的,我能做些什麼?

編輯: 這裏是代碼,你人送我,我cahnged他所以菲茨我的目標,將它的工作?

public ConcurrentQueue<Array> messageQueue = new ConcurrentQueue<Array>(); 
public void Example() 
     { 
      var thread = new Thread(
      () => 
      { 
       while (true) 
       { 
        Array array; 
        byte[] byteArray = {}; 
         if (messageQueue.Count > 0) 
         { 
          messageQueue.TryDequeue(out array); 
          foreach (byte result in array) 
          { 
           byteArray[byteArray.Length] = result; 
          } 
          controllernp.Write(byteArray, 0, 100); 
         } 

        Thread.Sleep(30); 
       } 
      }); 
      thread.IsBackground = true; 
      thread.Start(); 
     } 
+2

它不會在任何地方。編寫代碼之前,您無法啓動該程序。 – 2010-10-22 17:28:43

+5

@Hans--這種態度並沒有什麼幫助。你至少可以指出程序的哪一部分是錯誤的,而不僅僅是一次沖洗。 – Dismissile 2010-10-22 17:32:09

+0

@Dis - 全部都是錯誤的。我無法明智地回答基於無法運行的代碼的問題。 – 2010-10-22 17:44:06

回答

1

如果您希望每X毫秒將隊列中的項目出隊,那麼爲什麼要使用定時器呢?產生圍繞無限循環旋轉的新線程要容易得多。

public class Example 
{ 
    private ConcurrentQueue<Array> m_Queue = new ConcurrentQueue<Array>(); 

    public Example(int intervalMilliseconds) 
    { 
    var thread = new Thread(
    () => 
     { 
     while (true) 
     { 
      Array array; 
      while (m_Queue.TryDequeue(out array)) 
      { 
      // Process the array here. 
      } 
      Thread.Sleep(intervalMilliseconds); 
     } 
     }); 
    thread.IsBackground = true; 
    thread.Start(); 
    } 

    public void Enqueue(Array array) 
    { 
    m_Queue.Enqueue(array); 
    } 
} 

更新:

不,你的方法不是線程安全的。問題在於你如何將物品出列。

if (messageQueue.Count > 0) 
{ 
    messageQueue.TryDequeue(out array); 
} 

它應該看起來像這樣。

if (messageQueue.TryDequeue(out array) 
{ 
} 

TryDequeue該方法返回,如果隊列爲空,所以它已經這樣做在一個原子操作檢查和dequeue假。

5

這取決於計時器的類型。大多數定時器(System.Timers.Timer或System.Threading.Timer),可以在後臺線程中運行使用線程池線程的Tick事件。在這種情況下,答案是「既不是」線程。

如果您的計時器是Windows窗體計時器或DispatcherTimer,它可能會導致異常,因爲它們需要在UI線程上運行,並且無法在後臺線程上運行。

3

這將取決於正是你所使用的定時器。 .NET Framework有幾個定時器;

  • System.Threading.Timer =可以在任何可用的線程上。
  • System.Windows.Forms.Timer =應該對 「UI」 線程。
  • System.Timer.Timer =可能是在任何可用的線索。

,可能更多的是我失蹤。

2

如前所述,有兩個計時器; System.Threading.Timer和System.Windows.Forms.Timer。第一種可以在任何線程上執行,除了它是從線程開始的線程(除非它是線程池的一部分,並且函數已經返回,那麼它最終可能會在那裏執行)。

第二種Windows表單種類,可以在您的線程或其他線程上執行。這取決於。

計時器需要一個窗口句柄,並且根據創建句柄的線程,Tick事件將在不同的線程上觸發。定時器使用的內部窗口是在第一次需要時創建的。最有可能的是,您已經在主(GUI)線程上創建了定時器,但不會在定時器內創建實際的窗口。爲確保在主線程上創建窗口,您必須首先啓動,然後至少停止計時器一次。 (它是在第一次啓動窗口時創建的。)

(如果您沒有得到它:計時器使用內部窗口接收tick事件。窗口在線程上創建,並且該線程需要讓消息循環運行,首先啓動定時器的線程將創建窗口並接收Tick事件,希望該線程正在運行一個消息循環。)