阻止并发访问的线程池

问题描述:

所以我运行一个查询和处理在返回同时使用一个名为StartJob功能,将在我的工作工作行:阻止并发访问的线程池

ThreadPool.QueueUserWorkItem(StartJob, job); 

的伟大工程,是非常快。但是现在我被告知当查询返回时,某些行可能具有与job.UserID相同的值,并且我们无法同时为相同的job.UserID值运行StartJob函数。问题是:如何使StartJob块执行,直到具有相同用户ID的StartJob的任何其他实例都已完成?

我确定有一种方法可以获得每个用户ID锁,但我不知道该怎么做。谢谢您的帮助。

+0

将不会有并发冲突如果您用同样的job.UserID StartJob,直到它的目标是像一个文件中的一些共享资源或数据库行。你可以在StartJob中展示你在做什么? –

+0

什么版本的.NET? 3.5还是4.0? – xanatos

+0

@invisible完全正确,我在StartJob中运行了更多查询,锁定了UserID所拥有的行,因此我们看到超时,因为这些长时间运行的查询正在锁定这些行。所以我想用一些特定于UserID的锁来启动StartJob,并在那里*地阻止它。 – powlette

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在所有线程之间是相同的,并且idjob.UserID

我将在.NET 4.0中加入,您可以使用SpinLock而不是lock。它有点快,但它的语法有点棘手。

使用任务并行库

var tasks = new Dictionary<int, Task>(); 

QueueJob(Job job) 
{ 
    lock(tasks) 
     if (tasks.ContainsKey(job.UserID)) 
     { 
     var newTask = tasks[job.UserID].ContinueWith(_=>StartJob(job)); 
     tasks[job.UserID] = newTask; 
     } 
     else 
      tasks[job.UserID] = Task.Factory.StartNew(()=>StartJob(job));     
} 
+0

不是task.ContinueWith,lastTask.ContinueWith – xanatos

+0

@xanatos yea修复了它。谢谢。 –

+0

+1可能更可读为http://pastebin.com/Hreck9VE – xanatos