一些旧代码的线程问题
我正在进行一个最近从 .net 1.1 升级到 .net 4.0 的项目。我们从自定义“ThreadPool”类中收到错误(是的,有人觉得需要编写自己的),现在我想知道它可能是什么。
以下代码引发错误:
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);
}
}
注释的代码是我获得代码的方式。不幸的是,我对这个项目根本不了解,只是来这里解决这个问题。我们看到的错误是:
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:
从表面上看,某些东西被触发为“可用”,而实际上它并不可用。我尝试用谷歌搜索这个并找到http://bbellomo.blogspot。 com/2007/03/object-synchronization-method-was.html 但这对我没有太大帮助,因为我不太了解他的问题和解决方案。
希望有人能给我一些提示。
谢谢!
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 following 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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于您使用的是自己的线程池机制。那么异常可能是因为在
lock
之后和调用Monitor.Pulse
之前线程发生了变化。根据 msdn,如果出现以下情况,此异常将在 Pulse 处抛出:编辑:或者您在第一次锁定后锁定在不同的线程中,“也许在将
WorkItem
出列并在池中启动它们的生产者线程中,您正在调用 < code>lock (this.workQueue.SyncRoot)" 在到达Monitor.Pulse(this.workQueue.SyncRoot);
之前。Since you are using your own thread pool mechanism. Then the exception probably because the thread has changed after the
lock
and before you callMonitor.Pulse
. according to msdn this exception will throw atPulse
if: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 callinglock (this.workQueue.SyncRoot)
" at that thread before reachingMonitor.Pulse(this.workQueue.SyncRoot);
.