c# - 我如何重新设计它以使其线程安全?

标签 c# multithreading timer

我继承了一个旧的 VB6 DLL 来控制工业机械。我已将其转换为 C#。除了一个功能外,它运行良好:VB6 版本通过定时器支持“异步”模型,该定时器每秒唤醒一次以更新一些机器并更新大量数据结构和全局变量。它逃脱了这一点,因为 VB6 实际上是单线程的,即使它可以通过排队事件在子例程调用之间或通过 DoEvent 执行来模拟异步性。

在 C# 中,我们有真正的异步处理,因为我正在使用的 System.Timers.Timer 会导致新线程运行。不幸的是,这意味着我们会遇到线程冲突,因为计时器线程试图操纵用户的应用程序线程也正在接触的项目。

警告:定时器线程操作的数据量大且种类繁多 - 数百种不同的数据结构、变量和标志在所有其他 DLL 调用中使用,因此不切实际只有几个关键部分来保护它。

理想情况下,最简单的方法是将计时器代码的工作转移到将在应用程序线程中运行的调用中,并仅使用计时器以某种方式触发它。但是如何呢?

这个 DLL 的测试应用程序碰巧是一个 WPF 程序,所以我们可能会使用某种 DispatchTimer 线程来解决这个问题在我们的测试用例中,但是我们没有依据假设用户的应用程序是基于 Dispatcher 的,因此它不是一个通用的解决方案。

最佳答案

如果计时器不必在每次关闭时都处理数据,您可以使用 Monitor.TryEnter(),并只声明一个同步对象。类似的东西。

private readonly object _syncObject = new object();

.....

private void ProcessingMethod(){

    if(Monitor.TryEnter(_syncObject))
    {
       try{
              //do some processing.
       }
       finally{
          Monitor.Exit(_syncObject);
       }
    }          
}

如果计时器确实必须在每个时间间隔处理,那么您需要使用 lock 语句。如果它的处理时间很长,您将需要编写防止计时器积压的逻辑。

我假设正在处理的对象不是在 WPF 上下文中创建的,或者由于某种原因您无法将上下文传递给处理方法。

关于c# - 我如何重新设计它以使其线程安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27068825/

相关文章:

java - 我想为游戏 java 实现一个计时器?

c# - Richtextbox绘制一条rtf线

java - RxJava 调度程序始终与 sleep 在同一线程中工作

python - 为什么此Python Tkinter秒表脚本崩溃?

具有多个可以在线程中执行的方法的 Java 类

C# SpinWait 实现长时间等待

c# - C# 中的线程与定时器

c# - 依赖注入(inject): single class (WCF service) having multiple dependencies (DB repositories) how to handle?

c# - 您将 SQL 语句放在您的 C# 项目中的什么位置?

c# - 类型或命名空间名称 'Ports' 在命名空间 'System.IO' 中不存在