有单线程的app阻止,直到特定事件发生,然后恢复

时间:2014-04-04 02:42:49

标签: c# multithreading events .net-4.0

我正在编写一个单线程脚本来对数据库进行一系列编程更改。 某些操作会导致数据库执行一些需要一段时间才能完全解决的内部操作。

目前,我的代码包含一个如下所示的方法:

public static void AwaitTemplatePropagation(this Connection conn, DBObject template)
{
    while ((int)template["TransactionCount"] > 0)
    {
        System.Threading.Thread.Sleep(100);
    }
}

基本上,它会每100毫秒轮询一次,直到未完成的事务计数达到0。

但是,也可以在DBObject类上订阅名为PropertyUpdated的事件,该事件将在TransactionCount属性更改时引发。我更愿意使用它并让服务器告诉我何时继续,而不是轮询。我想它看起来应该是这样的:

public static void AwaitTemplatePropagation(this Connection conn, DBObject template)
{
    template.PropertyUpdated += ???; // Something?

    template.RegisterForPropertyUpdates(new string[] { "TransactionCount" });

    // Magic happens?

    template.UnregisterPropertyUpdates(new string[] { "TransactionCount" });
    template.PropertyUpdated -= ???; // Unsubscribe the event handler
    // Return to the calling function in the main thread
}

我无法搞清楚的是,如何编写一个只设置订阅的函数,然后阻止直到PropertyChangedEvent触发“TransactionCount现在为零”?那时我想删除订阅并将执行返回到我在主脚本中间的位置。

我使用的是.NET 4.0,因此async / await关键字不可用。我不确定他们会不会有所帮助。

1 个答案:

答案 0 :(得分:2)

您可以使用ManualResetEventSlim

private static ManualResetEventSlim _event = new ManualResetEventSlim (false);

public static void AwaitTemplatePropagation(this Connection conn, DBObject template)
{
    template.PropertyUpdated += OnPropertyUpdated; // Something?

    template.RegisterForPropertyUpdates(new string[] { "TransactionCount" });

    // Magic happens?
    // if you are using this method many times you have to reset the event first
    _event.Reset(); //Sets the state of the event to nonsignaled, which causes threads to block.
    _event.WaitHandle.WaitOne();

    template.UnregisterPropertyUpdates(new string[] { "TransactionCount" });

    // Return to the calling function in the main thread
 }

public void OnPropertyUpdated(...)
{
    _event.Set();
}

ManualResetEventSlim performance