线上通信 - 手动重置事件

时间:2014-05-28 14:03:32

标签: c# .net multithreading winforms

我正在尝试建立一个暂停并在线程之间进行通信。我在启动时为两个表单生成两个线程,一个是用于mainwindow的mainthread和用于form2的第二个线程,

 var thread = new Thread(ThreadStart);
        thread.TrySetApartmentState(ApartmentState.STA);
        thread.Start();


    private static void ThreadStart()
        {
            Application.Run(new SecondForm()); // other form started on its own UI thread
        }

Mainwindow上有一个按钮,点击哪个线程会为不同的操作生成 - 它会在没有暂停的情况下执行,直到预定的作业完成。

在第二种形式中,我有两个按钮停止,并开始点击我应该能够停止并启动主窗口(所有子线程)。

为此,我宣布 public static ManualResetEvent mre = new ManualResetEvent(false);

在program.cs中启动了两个UI线程 并尝试在开始和停止时从第二个表单调用它

private void btnStop_Click(object sender, EventArgs e)
    {
        Invoke((MethodInvoker) delegate
        {
            Program.mre.WaitOne(); 
        });
    }

    private void btnStart_Click(object sender, EventArgs e)
    {
        Invoke((MethodInvoker) delegate
        {
            Program.mre.Set();
        });
    }

一旦我点击主窗口上的按钮继续进行一系列操作,我尝试点击第二种形式的STOP按钮,这将禁用第二种形式,主窗口的操作继续,请让我知道我哪里出错了。

2 个答案:

答案 0 :(得分:1)

除了这是一个完全愚蠢的线程设计这一事实外,还有两个问题:

  • 您在第二个表单上Invoke,因此您正在阻止其消息循环。相反,您可能希望mainWindow.Invoke( ... )
  • 当主窗口生成工作线程时,即使这样也无济于事。它只会停止表单的消息循环,而不是它已经生成的线程。

答案 1 :(得分:0)

我找到了问题的解决方案。当我点击暂停按钮时,我设置了一个bool,表示继续为false,并在实际调用函数的循环中使用此变量。

在我拥有循环的同一个类中,我将手动重置事件初始化,当continue为false时,我调用mre.WaitOne(),这将暂停执行当前线程而不会对其他线程造成任何伤害。

单击Play时,我正在设置手动重置事件对象,该对象将重新启动线程。