System.Threading.Timer回调中的关键部分

时间:2022-07-21 20:38:35

In my application I have a number of System.Threading.Timer instances. There is a posibility that two of them will overlap each other. The problem is that there's a critical section in the callback method. Is it my concern to provide appropriate synchronization or does framework provide a solution?

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

There were some doubts about question, so I'll make it more clear: I have no synchronization at the moment in the callback.

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

2 个解决方案

#1


3  

Is it my concern to provide appropriate synchronization

提供适当的同步是我的关注吗?

If it is critical and it should have mutually exclusive access than yes you need to take care of it yourself.

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

does framework provide a solution

框架是否提供了解决方案

Framework does provide multiple tools to do locking and monitor. It depends on your requirement what you need. You need to take a look here to see what framework provides.

Framework确实提供了多种工具来进行锁定和监控。这取决于您的要求您需要什么。您需要查看此处以查看框架提供的内容。

The lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released.

lock关键字确保一个线程不进入代码的关键部分,而另一个线程处于临界区。如果另一个线程试图输入锁定的代码,它将等待,阻止,直到该对象被释放。

You also have the option to use Mutex

您还可以选择使用互斥锁

When two or more threads need to access a shared resource at the same time, the system needs a synchronization mechanism to ensure that only one thread at a time uses the resource. Mutex is a synchronization primitive that grants exclusive access to the shared resource to only one thread. If a thread acquires a mutex, the second thread that wants to acquire that mutex is suspended until the first thread releases the mutex.

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

#2


1  

You definately have to "concern yourself" with it. If you choose not to, then you will introduce race conditions to your application and therefore unwanted behaviour.

你肯定不得不“关注自己”。如果您选择不这样做,那么您将为您的应用程序引入竞争条件,从而引入不必要的行为。

.NET offers a number of solutions, each of which have pros and cons. A brief list could include:

.NET提供了许多解决方案,每个解决方案都有优缺点。简要列表可包括:

  • Locks - I would say the simplist method. You would lock the shared memory that would be altered on the callback method. This way, only one thread can alter the object at a time. The downfall of this is if you have multiple threads always waiting for a lock to be released, then what's the point. The overhead of the lock would probably make everything slower than just using a single thread.

    锁 - 我会说简单的方法。您将锁定将在回调方法上更改的共享内存。这样,一次只能有一个线程改变对象。如果您有多个线程总是在等待释放锁定,那么这就失败了。重点是什么。锁的开销可能会使一切变慢,而不仅仅是使用单个线程。

  • Read/Write Locks - Similar to a lock, but now instead of doing a universal lock, you could have multiple threads reading from shared memory and only locking everything out when you require a write lock. This can allow for multiple threads to safely access memory at the same time.

    读/写锁 - 类似于锁,但现在不是执行通用锁,而是可以让多个线程从共享内存中读取,并且只在需要写锁时才锁定所有内容。这可以允许多个线程同时安全地访问内存。

  • TPL (Task Parallel Libary) - .NET specific. This most likely would be your most complicated solution, and might require a data structure change. But I wanted to throw it in here because I think it offers a very strong solution. A simple explanation behing using TPL, is to only have one thread operate on the shared memory at a time, however don't block other threads while doing so... So this avoids the problem of having multiple threads messing with your object and causing race conditions, but you also don't tie up several threads. A good starting point might be to look at the Data Flow document and see which data structure best fits your needs.

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

There are several more options, so don't take this as a complete list... I would push for TPL for most cases...

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

#1


3  

Is it my concern to provide appropriate synchronization

提供适当的同步是我的关注吗?

If it is critical and it should have mutually exclusive access than yes you need to take care of it yourself.

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

does framework provide a solution

框架是否提供了解决方案

Framework does provide multiple tools to do locking and monitor. It depends on your requirement what you need. You need to take a look here to see what framework provides.

Framework确实提供了多种工具来进行锁定和监控。这取决于您的要求您需要什么。您需要查看此处以查看框架提供的内容。

The lock keyword ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released.

lock关键字确保一个线程不进入代码的关键部分,而另一个线程处于临界区。如果另一个线程试图输入锁定的代码,它将等待,阻止,直到该对象被释放。

You also have the option to use Mutex

您还可以选择使用互斥锁

When two or more threads need to access a shared resource at the same time, the system needs a synchronization mechanism to ensure that only one thread at a time uses the resource. Mutex is a synchronization primitive that grants exclusive access to the shared resource to only one thread. If a thread acquires a mutex, the second thread that wants to acquire that mutex is suspended until the first thread releases the mutex.

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

#2


1  

You definately have to "concern yourself" with it. If you choose not to, then you will introduce race conditions to your application and therefore unwanted behaviour.

你肯定不得不“关注自己”。如果您选择不这样做,那么您将为您的应用程序引入竞争条件,从而引入不必要的行为。

.NET offers a number of solutions, each of which have pros and cons. A brief list could include:

.NET提供了许多解决方案,每个解决方案都有优缺点。简要列表可包括:

  • Locks - I would say the simplist method. You would lock the shared memory that would be altered on the callback method. This way, only one thread can alter the object at a time. The downfall of this is if you have multiple threads always waiting for a lock to be released, then what's the point. The overhead of the lock would probably make everything slower than just using a single thread.

    锁 - 我会说简单的方法。您将锁定将在回调方法上更改的共享内存。这样,一次只能有一个线程改变对象。如果您有多个线程总是在等待释放锁定,那么这就失败了。重点是什么。锁的开销可能会使一切变慢,而不仅仅是使用单个线程。

  • Read/Write Locks - Similar to a lock, but now instead of doing a universal lock, you could have multiple threads reading from shared memory and only locking everything out when you require a write lock. This can allow for multiple threads to safely access memory at the same time.

    读/写锁 - 类似于锁,但现在不是执行通用锁,而是可以让多个线程从共享内存中读取,并且只在需要写锁时才锁定所有内容。这可以允许多个线程同时安全地访问内存。

  • TPL (Task Parallel Libary) - .NET specific. This most likely would be your most complicated solution, and might require a data structure change. But I wanted to throw it in here because I think it offers a very strong solution. A simple explanation behing using TPL, is to only have one thread operate on the shared memory at a time, however don't block other threads while doing so... So this avoids the problem of having multiple threads messing with your object and causing race conditions, but you also don't tie up several threads. A good starting point might be to look at the Data Flow document and see which data structure best fits your needs.

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

There are several more options, so don't take this as a complete list... I would push for TPL for most cases...

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