【问题标题】:Critical section in System.Threading.Timer callbackSystem.Threading.Timer 回调中的关键部分
【发布时间】:2013-12-19 12:52:56
【问题描述】:

在我的应用程序中,我有许多 System.Threading.Timer 实例。它们中的两个可能会相互重叠。问题是回调方法中有一个关键部分。我关心的是提供适当的同步还是框架提供了解决方案?

对问题有一些疑问,所以我会说得更清楚:我在回调中暂时没有同步。

【问题讨论】:

  • 当您说“临界区”时,究竟是什么意思?
  • 更具体地说,我的回调中有一个连接对象。
  • 很难看出这个问题的重点。如果您在回调中有“关键部分”,那么您已经在提供同步。根据需要。

标签: c# .net concurrency timer mutex


【解决方案1】:

我是否关心提供适当的同步

如果它很重要并且应该具有互斥访问权限,那么您需要自己处理它。

框架是否提供解决方案

Framework 确实提供了多种工具来进行锁定和监控。这取决于您的要求,您需要什么。你需要看看here 看看框架提供了什么。

lock 关键字确保一个线程不进入代码的临界区,而另一个线程在临界区。如果另一个线程试图输入一个锁定的代码,它会等待、阻塞,直到对象被释放。

您还可以选择使用Mutex

当两个或多个线程需要同时访问一个共享资源时,系统需要一种同步机制来确保一次只有一个线程使用该资源。 Mutex 是一种同步原语,它只将共享资源的独占访问权限授予一个线程。如果一个线程获取了一个互斥锁,第二个想要获取该互斥锁的线程将被挂起,直到第一个线程释放该互斥锁。

【讨论】:

  • 这回答了我的问题。我不确定是否可以同时调用 Timer 回调。
【解决方案2】:

你一定要“关心自己”。如果您选择不这样做,那么您将在您的应用程序中引入竞争条件,从而导致不需要的行为。

.NET 提供了许多解决方案,每种解决方案都有利有弊。一个简短的列表可能包括:

  • - 我会说最简单的方法。您将lock 将在callback 方法上更改的共享内存。这样,一次只有一个线程可以更改对象。这样做的缺点是如果你有多个线程总是在等待一个锁被释放,那么有什么意义呢。锁的开销可能会使一切都比仅使用单个线程慢。

  • 读/写锁 - 与lock 类似,但现在您可以让多个线程从共享内存中读取,并且仅在您锁定所有内容时才锁定所有内容。需要write lock。这可以允许多个线程同时安全地访问内存。

  • TPL(任务并行库) - 特定于 .NET。这很可能是您最复杂的解决方案,并且可能需要更改数据结构。但我想把它放在这里,因为我认为它提供了一个非常强大的解决方案。使用 TPL 的一个简单解释是,一次只有一个线程在共享内存上操作,但是这样做时不要阻塞其他线程......所以这避免了多个线程弄乱你的对象并导致的问题竞争条件,但您也不会占用多个线程。一个好的起点可能是查看Data Flow 文档,看看哪种数据结构最适合您的需求。

还有几个选项,所以不要把它当成一个完整的列表......我会在大多数情况下推动TPL......

【讨论】:

  • 我知道同步方法。您一定误解了我的问题,但感谢您的详尽回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
  • 2012-02-09
  • 2020-02-15
  • 1970-01-01
  • 2014-04-20
相关资源
最近更新 更多