Threading problem with some old code
I'm on a project that recently upgraded from .net 1.1 to .net 4.0. We're getting an error from a custom "ThreadPool" class (yes, someone felt the need to write thier own), and now I'm wondering what it might be.
The error is thrown from the followi开发者_JS百科ng code:
private void Submit(WorkItem work)
{
this.AdjustPoolSize();
lock (this.workQueue.SyncRoot)
{
//Monitor.Enter(workQueue);
this.workQueue.Enqueue(work);
Monitor.Pulse(this.workQueue.SyncRoot);
//Monitor.Exit(workQueue);
}
}
The commented code is how I was handed the code. Unfortunatly, I don't know much about this project at all and am only here to fix this issue. The error we see is :
System.Threading.SynchronizationLockException was unhandled by user code
Message=Object synchronization method was called from an unsynchronized block of code.
Source=mscorlib
StackTrace:
at System.Threading.Monitor.ObjPulse(Object obj)
at System.Threading.Monitor.Pulse(Object obj)
at CustomThreadPoolObject.Submit(WorkItem work) in D:\...\Threading.cs:line 1438
at CustomThreadPoolObject.Submit(WaitCallback callback, Object state) in D:\...\Threading.cs:line 1349
at SomeGroupProcessFunctionality.Submit(PooledThread thread, TaskInfo task, String appServer, Hashtable batchHandleTable) in D:\...\ProcessGroup.cs:line 143
at System.Runtime.Remoting.Messaging.Message.Dispatch(Object target, Boolean fExecuteInContext)
at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)
InnerException:
By the looks of it, something is being triggered as "available" when it really isn't. I tried to google this and found http://bbellomo.blogspot.com/2007/03/object-synchronization-method-was.html but that didn't help me so much as I didn't quite understand both his issue and resolution.
Hopefully someone can give me some hints.
Thanks!
Since you are using your own thread pool mechanism. Then the exception probably because the thread has changed after the lock
and before you call Monitor.Pulse
. according to msdn this exception will throw at Pulse
if:
The calling thread does not own the lock for the specified object.
Edit: Or you are locking in different thread after your first lock, "maybe at the producer thread that will dequeue the WorkItem
and start them in the pool, you are calling lock (this.workQueue.SyncRoot)
" at that thread before reaching Monitor.Pulse(this.workQueue.SyncRoot);
.
精彩评论