我正在检查我的队列是否已满或
lock (SizeQueueProperty.Locker)
{
while (_queue.Count >= _maxSize)
{
SizeQueueProperty.Waiting = true;
Monitor.Wait(SizeQueueProperty.Locker);
}
_queue.Enqueue(item);
if (_queue.Count == 1)
{
// wake up any blocked dequeue
SizeQueueProperty.Waiting = false;
Monitor.PulseAll(SizeQueueProperty.Locker);
}
}
public static class SizeQueueProperty
{
public volatile static object Locker = new object();
public volatile static bool Waiting;
}
如果然后在另一个线程中的另一个类中检查此代码:
if (SizeQueueProperty.Waiting)
{
Log.Info("Waiting for continue on crawling");
Monitor.Wait(SizeQueueProperty.Locker);
....
More code
}
...
已满,我想等待该队列变空,然后继续执行线程。但我总是得到meesage:
从非同步调用对象同步方法 代码块。
为什么?
答案 0 :(得分:2)
Wait
方法。
释放对象的锁定并阻止当前线程直到它 重新获得锁定。
只有在您持有Wait
,
lock
if (SizeQueueProperty.Waiting)
{
Log.Info("Waiting for continue on crawling");
Monitor.Wait(SizeQueueProperty.Locker);
}
此代码似乎没有锁定,是吗?
答案 1 :(得分:0)
我也有这个问题 - "对象同步方法是从一个不同步的代码块中调用的。"我将Monitor.Enter(变量)称为值类型。在我的实例中,它是一个整数。我通过使用对象的实例解决了它。 RowIndex作为我想要锁定的整数。所以我把我的代码改为:
Private SyncObj As New Object
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Threading.Monitor.Enter(SyncObj)
ToolStripProgressBar1.Value = RowIndex / Dt.Rows.Count * 100
ToolStripStatusLabel1.Text = (Dt.Rows.Count - RowIndex).ToString & " left"
Threading.Monitor.Exit(SyncObj)
End Sub
然后在我的其他线程中,我会在对RowIndex进行任何更改之前锁定SyncObj。工作得很好!
答案 2 :(得分:0)
在我看来,.NET 4.5中原始代码的需要可以通过使用来实现 BlockingCollection