因此,我正在运行查询并使用名为 StartJob 的函数处理同时返回的行,该函数将对我的作业起作用:
ThreadPool.QueueUserWorkItem(StartJob, job);
效果很好,速度非常快。但是现在我被告知,当查询返回时,某些行可能具有job.UserID的相同值,并且对于相同的job.UserID值,我们不能同时运行StartJob函数。问题是:在具有相同UserID的其他任何StartJob实例完成之前,如何执行StartJob块执行?
我敢肯定有一种获取每个用户ID锁的方法,但是我不知道该怎么做。谢谢您的帮助。
最佳答案
HashSet<int> hs = new HashSet<int>(); // In common with all the threads
int id = 1; // Your id
// This is the body of your Thread. You pass it the id as you want.
// A closure on it, or as a parameter of the thread.
// This will begin with short spins, every time trying to add the id to the hashset.
// SpinUntil stops when the lambda function returns true.
SpinWait.SpinUntil(() =>
{
lock (cd)
{
return hs.Add(id);
}
});
// OR, if you know the operation is slow, or < .NET 4.0
// This is clearer. The thread yields until it can add the id to the hashset.
while (true)
{
lock (hs)
{
if (hs.Add(id))
{
break;
}
}
Thread.Yield();
}
// End of the variant
// Remember the try/finally! It's important in case of exceptions!!!
try
{
// Put here your code
// Put here your code
// Put here your code
}
finally
{
lock (hs)
{
hs.Remove(id);
}
}
有两个版本,一个适用于简短的
StartJob
,仅在.NET 4.0上有效,而另一个适用于.NET> = 3.5。显然,
hs
是所有线程之间的共同点,id
是job.UserID
。我将在.NET 4.0中添加您可以使用
SpinLock
而不是lock
。它速度更快一些,但是其语法有点棘手。关于c# - 阻止并发访问ThreadPool,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7673677/