使用BeginInvoke的UI更新挂起,直到线程完成?

时间:2011-05-02 00:52:09

标签: c# multithreading events forms invoke

我有1个类(acBL)处理2个线程(fpDoWork)。在fpDoWork中完成的任何工作都会将事件触发回acBL类。在我的表单上,我声明了acBL类并在acBL上关联了事件处理程序 - 这样,无论何时调用事件,它都应该“更新”UI。

未发生的事情是,当每个fpDoWork线程启动时,它会执行操作,调用ProcessingEvent并进入frmMain.handlerProcessing1事件。它到达了调用this.BeginInvoke(新的Processing2Event(handlerProcessing2),status)的程度,然后它就会挂起并等待线程完成其工作,然后再继续更新UI。我试过了.Invoke,但这种方法似乎挂了。有什么想法吗?

frmMain内的代码

代码早期:

this.acBL.Processing1Event += new acBL.Processing1(handlerProcessing1);
this.acBL.Processing2Event += new acBL.Processing2(handlerProcessing2);

处理程序:

private void handlerProcessing1(string status) {
  if (InvokeRequired) {
    this.BeginInvoke(new MethodInvoker(this.Refresh));
    this.BeginInvoke(new Processing1Event (handlerProcessing1), status);

  }
  else {
    Console.WriteLine("UPDATING 1: "+status);
    lblForProcessing1.Text = status;
    this.Refresh();
    return;
  }
}


private void handlerProcessing2(string status) {
  if (InvokeRequired) {
    this.BeginInvoke(new MethodInvoker(this.Refresh));
    this.BeginInvoke(new Processing2Event (handlerProcessing2), status);

  }
  else {
    Console.WriteLine("UPDATING 2: "+status);
    lblForProcessing2.Text = status;
    this.Refresh();
    return;
  }
}

acBL中的代码

在主要方法中:

bool thread1Complete = false;
fpDoWork fpDoWork1 = new fpDoWork();
fpDoWork1.GUIForm = frmMain;
fpDoWork1.ProcessingEvent += new fpDoWork.Processing(handlerProcessing1Event);
fpDoWork1.ThreadCompleteEvent += new fpDoWork.ThreadComplete(thread1Complete);
Thread fpDoWork1Thread= new Thread(new ThreadStart(fpDoWork1.StartWork));

bool thread2Complete = false;
fpDoWork fpDoWork2 = new fpDoWork();
fpDoWork2.GUIForm = frmMain;
fpDoWork2.ProcessingEvent += new fpDoWork.Processing(handlerProcessing2Event);
fpDoWork2.ThreadCompleteEvent += new fpDoWork.ThreadComplete(thread2Complete);
Thread fpDoWork2Thread= new Thread(new ThreadStart(fpDoWork2.StartWork));

Console.WriteLine("Work for 1 Thread started...");
fpDoWork1Thread.Start();
Console.WriteLine("Work for 2 Thread started...");
fpDoWork2Thread.Start();

while (!thread1Complete && !thread2Complete ) {
  if (!thread1Complete && !thread2Complete ) {
    Console.WriteLine("Waiting for both copying threads...");
  }
  else if (!thread1Complete && thread2Complete ) {
    Console.WriteLine("Waiting for thread 1...");
  }
  else if (thread1Complete && !thread2Complete ) {
    Console.WriteLine("Waiting for thread 2...");
  }
  Thread.Sleep(1000);
}
Console.WriteLine("All done");

否则代码中的位置:

public delegate void ProcessingFor1 (string filename);
public delegate void ProcessingFor2 (string filename);
public event ProcessingFor1 ProcessingEventFor1;
public event ProcessingFor2 ProcessingEventFor2;


private void handlerProcessing1Event(string filename) {
  Console.WriteLine("Processing 1: " + filename);
  ProcessingEventFor1(filename);
}

private void handlerProcessing1Event(string filename) {
  Console.WriteLine("Processing 2: " + filename);
  ProcessingEventFor2(filename);
}

1 个答案:

答案 0 :(得分:0)

您的UI未更新的原因是主要UI线程卡在 while ()循环中。 BackgroundWorker 是您的朋友

尽量避免在一个线程中创建线程并坐在那里等待它们完成,首先是线程的错误使用

欢呼声