簡體   English   中英

有沒有辦法防止事件處理程序自行觸發?

[英]Is there a way to prevent an event handler from firing over itself?

我有一個可以快速連續發生的事件的事件處理程序。 在某些情況下,當事件再次觸發時(毫秒內),處理程序仍將執行。

有沒有辦法讓這些處理程序......串行? 那么,在事件調用 #1 完成之前,事件調用 #2 無法啟動?

如果這是一個糟糕的想法,為什么? 這是一個在后台無人值守運行的批處理過程,因此我並不十分擔心一個調用阻塞另一個調用可能會出現性能問題。

使用多線程控制lock 這樣可以防止您的代碼在同一時刻多次運行。

EDITED
例:

public class Foo
{
    private static object _lockKey = new object();

    private void YourEventHandlerMethod(object sender, EventArgs e)
    {   
        lock (_lockKey)
        {
            // the code you put inside this block will be execute only
            // once at time.

            // If a second call has the intention to use this block before
            // the conclusion of the first call, the second call (the thread)
            // will be put in hold.
        }
    }
}

有一些選項可以序列化事件的處理,這些事件可以從多個線程並發或通過重新加密/遞歸在同一線程上觸發。

選項之一是使用任務計划程序。 在您的方案中,任務計划程序的目的是使回調排隊,以便以后進行串行執行。 諸如此類的任務計划程序的一個著名概念示例是WinForms消息循環(以Application.Run開始,以Control.BeginInvoke排隊)和WPF Dispatcher循環(以Dispatcher.Run開始,以Dispatcher.BeginInvokeDispatcher.InvokeAsync排隊)。

TPL任務計划程序的一個StaTaskScheduler但非常有用的實現是Stephen Toub的StaTaskScheduler 我在這里這里都發布了一些基於它的代碼(后一個是來自一個非常接近的問題, 異步執行的隊列操作/委托 )。

此處介紹了另一個選擇: 任務排序和重新登錄

在這種情況下,將處理程序作為任務組成,每個新的處理程序都在前一個任務完成后啟動。

八年后,我發現了阻塞收藏的樂趣。

與其讓事件處理程序完成這項工作,我還可以將一些數據放入一個阻塞集合中,並有一個單獨的線程來處理它。

private readonly BlockingCollection<Whatever> queue = new BlockingCollection<Whatever>();

Task.Run(() =>
{
  while (!queue.IsCompleted) {

   // Do whatever

  }
}

// Then just add a bunch of stuff to it
queue.Add(new Whatever());

// It will just keep working the queue in a separate thread, going back for a new Whatever whenever it's done

// You can even start multiple threads to work the queue. They won't interfere with each other

暫無
暫無

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

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