我在理解多线程方面遇到了问题。我会尝试解释并希望你能理解我的意思。
我有一个班级form1
(继承自Form
)。这个表格可以打开几次。当打开一个工作线程时,工作线程将以全局同步对象开始,我传递该对象创建表单。
因此每个表单都有相同的对象进行同步。这是必要的,因为还有另一个类可以完成一些工作(只有一个对象可以存活)。不允许同时完成这项工作。
我的问题如下:
如何在不阻塞所有线程的情况下将所有线程与第二个工作类同步?
// from this form can be exist several objects
public partial class form1 : Form
{
...
private Object synchronizedObject;
public void SetSynchronizedObject(Object o)
{
synchronizedObject = o;
}
// executed threaded
public void DoWork()
{
while (bDoWork)
{
try
{
bool bLock = Monitor.TryEnter(synchronizedObject);
if (!bLock)
{
if (bDoWork)
{
this.BeginInvoke((MethodInvoker)delegate()
{
if (panel1 != null)
panel1.Visible = true;
});
}
Monitor.Enter(synchronizedObject);
if (bDoWork)
{
this.BeginInvoke((MethodInvoker)delegate()
{
if (panel1 != null)
panel1.Visible = false;
});
}
}
i++;
if (bDoWork)
{
this.BeginInvoke((MethodInvoker)delegate()
{
if (textBox != null)
textBox.Text = i.ToString();
});
}
}
finally
{
Monitor.Exit(synchronizedObject);
}
Thread.Sleep(1);
}
}
然后有form2
。当form2
完成其工作时,应阻止所有线程。我的代码存在的问题是form1
正在阻止。
答案 0 :(得分:1)
您尝试解决的问题可以通过“工作人员”很好地解决。创建一个ConcurrentQueue<T>
,在那里添加“工作”。启动工作线程(一次)
ConcurrentQueue<T> _q;
void Worker()
{
while (true)
{
T element = _q.Dequeue();
if (element == null)
break;
// do work with element here
// obviously, it will happen one at a time
}
}
示例中的代码假定您不需要结果
更好的方法是使用“Limited concurrency SynchronizationContext”,在这种情况下,您可以使用await / async。
答案 1 :(得分:0)
您希望使用共享的synchronizedObject
来同步您的主题。这是一个好主意,但你真的确定synchronizedObject
确实在所有实例之间共享吗?有一种非常简单的方法可以真正确保这一点,而无需使用(潜在的错误)SetSynchronizedObject
方法。
private static readonly Object synchronizedObject = new object();
现在您确保 synchronizedObject
在所有实例之间共享。
我不确定这是你实施中的错误部分(这取决于你如何调用SetSynchronizedObject
),但很容易确保那里没有潜在的错误。< / p>