c# - 在 C# 中无限/定期执行代码的最佳实践

标签 c# .net winapi events execution

通常在我的代码中,我启动的线程基本上是这样的:

void WatchForSomething()
{
    while(true)
    {
        if(SomeCondition)
        {
             //Raise Event to handle Condition
             OnSomeCondition();
        }
        Sleep(100);
    }
}

只是想知道某些条件是否为真(例如,如果有一个没有事件的错误编码库,只有 bool 变量,我需要它们的“实时 View ”)。

我想知道是否有更好的方法来完成这种工作,例如 Hook Windows 函数,它可以在所有 x 秒内运行我的方法。或者我应该为我的应用程序编写一个全局事件,提高所有 x 秒并让他像这样调用我的方法:

//Event from Windows or selfmade
TicEvent += new TicEventHandler(WatchForSomething));

然后这个方法:

    void WatchForSomething()
    {
        if(SomeCondition)
        {
             //Raise Event to handle Condition
             OnSomeCondition();
        }
    }

所以,我希望这不会因为是一个“主观问题”或其他什么而关闭,我只是想知道这种工作的最佳实践是什么。

最佳答案

编写长时间运行的事件处理代码不一定有“最佳方法”。这取决于您正在开发的应用程序类型。

您展示的第一个示例是您经常看到编写长时间运行线程的主要方法的惯用方式。虽然通常希望使用互斥锁或可等待事件同步原语,而不是而不是调用 Sleep() - 它是用于实现事件处理循环的典型模式。这种方法的好处是它允许专门的处理在单独的线程上运行——允许应用程序的主线程执行其他任务或保持对用户输入的响应。这种方法的缺点是它可能需要使用内存屏障(例如锁)来确保共享资源不被破坏。它还使更新 UI 变得更加困难,因为您通常必须将此类调用编码回 UI 线程。

第二种方法也经常使用 - 特别是在已经具有事件驱动 API 的系统中,例如 WinForms、WPF 或 Silverlight。使用计时器对象或空闲事件是典型的方法如果没有用户启动的事件触发您的处理,则可以在其中进行定期背景检查。这样做的好处是很容易交互和更新用户界面对象(因为它们可以直接从同一个线程访问),并且它减少了对 protected 数据的锁和互斥锁的需要。这种方法的一个潜在缺点是,如果必须执行的处理非常耗时,它会使您的应用程序无法响应用户输入。

如果您没有编写具有用户界面(例如服务)的应用程序,那么第一种形式的使用频率要高得多。

顺便说一句......如果可能的话,最好使用像EventWaitHandle这样的同步对象。或 Semaphore在工作可以处理时发出信号。 这使您可以避免使用 Thread.Sleep 和/或 Timer 对象。它减少了可以执行工作和触发事件处理代码之间的平均延迟,并且最大限度地减少了使用后台线程的开销,因为它们可以由运行时环境更有效地调度并且不会消耗任何 CPU 周期直到有工作要做。

还值得一提的是,如果您所做的处理是为了响应与外部源(MessageQueues、HTTP、TCP 等)的通信,您可以使用 WCF 等技术。提供事件处理代码的骨架。 WCF 提供的基类大大简化了异步响应通信事件事件的客户端和服务器系统的实现。

关于c# - 在 C# 中无限/定期执行代码的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4451659/

相关文章:

c++ - 打印线程(c++)的调用堆栈,是否使用 StackWalker?

sockets - Winsock 中是否有与 TCP_CORK 等效的东西?

C# GridView/Radio Button 没有触发事件……为什么?

c# - 更改 UI RectTransform 位置

c# - 自定义映射 Dapper.NET

c# - WPF MVVM 异步事件调用

c - 我的自定义 ListView 控件中发生了什么导致滚动时部分或完全不重新绘制行?

c# - 使用C#为每三位数字添加逗号

c# - 带有资源文件的居中 DataGridTextColumn 标题中的换行符

c# - 如何获取 IdentityReference 对象的显示名称?