- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我继承了一个旧的 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/
我是一名优秀的程序员,十分优秀!