Igb*_*man 9 .net multithreading reentrancy
关于多线程编程似乎有很多东西需要学习,而且它有点令人生畏.
对于我目前的需求,我只想防止在完成之前从另一个线程再次调用的方法,我的问题是:
这是一种使方法线程安全的充分(安全)方法吗?
class Foo
{
bool doingWork;
void DoWork()
{
if (doingWork) // <- sophistocated thread-safety
return; // <-
doingWork = true;
try
{
[do work here]
}
finally
{
doingWork = false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果这还不够,最简单的方法是什么?
编辑:有关场景的更多信息:
Foo只有一个例子
将在System.Timers.Timer的Elapsed事件上从ThreadPool线程调用Foo.DoWork().
通常Foo.DoWork()会在下次调用之前完成eons,但是我想编码它运行时间很长的机会,并在完成之前再次调用.
(我也不够聪明,不能确定这个问题是否可以被标记为与语言无关,所以我没有.开明的读者,如果适用,请随意这样做.)
您的代码不是线程安全的.您应该使用lock关键字.
在您当前的代码中:
if (doingWork)
return;
// A thread having entered the function was suspended here by the scheduler.
doingWork = true;
Run Code Online (Sandbox Code Playgroud)
当下一个线程通过时,它也将进入该功能.
这就是lock应该使用构造的原因.它基本上与您的代码相同,但没有线程在中间被中断的风险:
class Foo
{
object lockObject = new object;
void DoWork()
{
lock(lockObject)
{
[do work here]
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,此代码的语义与原始语义略有不同.此代码将导致第二个线程进入等待然后执行工作.您的原始代码使第二个线程中止.为了更接近原始代码,lock不能使用C#语句.Monitor必须直接使用底层构造:
class Foo
{
object lockObject = new object;
void DoWork()
{
if(Monitor.TryEnter(lockObject))
{
try
{
[do work here]
}
finally
{
Monitor.Exit(lockObject);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3930 次 |
| 最近记录: |