簡體   English   中英

在一個線程中引發事件以調用第二個線程中的方法

[英]Raise event in one thread to invoke methods in a second thread

我正在開發一個程序,它可以響應來自互聯網套接字的事件,也可能來自定時器。 使用兩個線程似乎很自然:

  • 一個主要計划
  • 第二個偵聽套接字,解析輸入並引發適當的事件。

其他要求:

  1. 應用程序不應該依賴UI線程(它可以作為控制台應用程序運行)。
  2. 主程序應該同步處理消息,即按照它們到達的順序。
  3. 主線程不能阻塞等待定時器(我想這意味着我必須在不同的線程上運行定時器)。

現在有些問題:-):

  1. 我猜測需求#1意味着我沒有內置消息泵,所以我不能使用套接字監聽器/定時器線程中的Invoke() 它是否正確?
  2. 如何在一個線程(例如監聽器)上安全地引發事件,並讓訂戶在另一個線程(主線程)上同步運行?
  3. 在后續處理程序完成之前,很可能會引發新事件。 在這種情況下會發生什么? CLR會在某個地方對事件進行緩沖,還是會被忽略?

最后但並非最不重要:我想我的目標是消息生產者/消費者范例的並行,但我想使用事件而不是消息。 你認為有更好的方法嗎?

謝謝,

波阿斯

編輯

我想首先解釋一下使用事件的動機。 該應用程序是一個自動交易引擎,必須響應市場中發生的事件(例如股票價格的變化)。 發生這種情況時,主線程上可能有多個訂閱者應該被調用,這是使用事件的經典場景。

我想我總是可以使用Producer / Consumer和一些消息隊列,並讓消費者在主線程上引發事件,但我認為可能有更直接的方式。

我認為使用消息將是最簡單的方法。 如果你使用的是C#4,這要歸功於BlockingCollection <>

所以有一個共享的BlockingCollection,其中Message是你的消息類。

然后在你的工作線程中你這樣做

var msgEnum = blockingCollection.GetConsumingEnumerable();

//Per thread
foreach( Message message in msgEnum )
{
   //Process messages here
}

這就對了。

GetConsumingEnumerable()將阻塞,直到有消息要處理。 然后它將從隊列中刪除消息,您的循環將處理它。

這有什么好處,你可以添加更多的線程,每個線程都有foreach循環。

完成后調用blockingCollection.CompletedAdding();

BTW隊列處理並發並將隊列消息同時排隊等。

希望這可以幫助

安德烈

您可以在線程之間實現共享隊列。 每當引發事件時,您都可以將其推入隊列中。 主線程是一個無限循環,它檢查新事件,從隊列中刪除它們,處理事件,當沒有更多事件時,它會休眠一段時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM