У меня есть приложение (frmMain), которое вызывает класс (ThreadBL), который запускает 2 потока (Thread1, Thread2).Когда Thread1 выполняет операции, я хочу иметь возможность отправлять обновления обратно через frmMain, аналогично Thread2 делает то же самое.
Вот некоторый расколотый код, который в основном и работает.У меня не было возможности проверить, работает ли этот конкретный код, но когда я запускаю исходный код, у меня появляется ошибка «Операция с несколькими потоками недопустима с многопоточностью».
Есть ли лучший способ обновления frmMain из потоков?Является ли этот код слишком исчерпывающим и ненужным?Любая обратная связь с благодарностью.
public class ThreadExample() {
private void ThreadExample() {};
public delegate void CurrentFileProcessing(string filename);
public event CurrentFileProcessing CurrentFileProcessingEvent;
public bool startCopying() {
CurrentFileProcessingEvent += new CurrentFileProcessing(handlerCurrentFileProcessing);
copyFiles();
return true;
}
public void copyFiles() {
CurrentFileProcessingEvent("Copying: file.xml");
}
private void handlerCurrentFileProcessing(string filename) {
Console.WriteLine("Processing: " + filename);
}
}
public class ThreadBL() {
private void ThreadBL() {};
public delegate void Thread1CurrentProcessing(string filename);
public delegate void Thread2CurrentProcessing(string filename);
public event Thread1CurrentProcessing Thread1CurrentProcessingEvent;
public event Thread2CurrentProcessing Thread2CurrentProcessingEvent;
private bool processingThread1 = false;
private bool processingThread2 = false;
public void processThreads() {
BackgroundWorker thread1BW = new BackgroundWorker();
thread1BW.DoWork += new DoWorkEventHandler(thread1Process);
thread1BW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(completeThread1);
thread1BW.RunWorkerAsync();
while (!processingThread1) {
Console.WriteLine("Waiting for thread1 to finish. TID: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(100);
}
BackgroundWorker thread2BW = new BackgroundWorker();
thread2BW.DoWork += new DoWorkEventHandler(thread2Process);
thread2BW.RunWorkerCompleted += new RunWorkerCompletedEventHandler(completeThread2);
thread2BW.RunWorkerAsync();
while (!thread2Done) {
Console.WriteLine("Waiting for thread2 to finish. TID: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(100);
}
}
private void thread1Process() {
ThreadExample thread1Example = new ThreadExample();
thread1Example.CurrentFileProcessingEvent += new ThreadExample.CurrentFileProcessing(handlerThread1CurrentProcessingEvent);
processingThread1 = thread1Example.startCopying();
}
private void completeThread1(object sender, RunWorkerCompletedEventArgs e) {
Console.WriteLine("Completed Thread1. TID: " + Thread.CurrentThread.ManagedThreadId);
processingThread1 = true;
}
private void thread2Process() {
ThreadExample thread2Example = new ThreadExample();
thread2Example.CurrentFileProcessingEvent += new ThreadExample.CurrentFileProcessing(handlerThread2CurrentProcessingEvent);
processingThread2 = thread2Example.startCopying();
}
private void completeThread2(object sender, RunWorkerCompletedEventArgs e) {
Console.WriteLine("Completed Thread1. TID: " + Thread.CurrentThread.ManagedThreadId);
processingThread2 = true;
}
private void handlerThread2CurrentProcessingEvent(string filename) {
Console.WriteLine("Thread2 Processing: " + filename);
Thread2CurrentProcessingEvent(filename);
}
}
public class frmMain {
private ThreadBL threadBL = new ThreadBL();
public void frmMain() {
threadBL.Thread1CurrentProcessingEvent += new ThreadExample.CurrentFileProcessing(handlerThread1ProgressEvent);
threadBL.Thread2CurrentProcessingEvent += new ThreadExample.CurrentFileProcessing(handlerThread2ProgressEvent);
threadBL.processThreads();
}
private void handlerThread1ProgressEvent(string progress) {
lblCopyingProgress.Invoke(new MethodInvoker(delegate { lblCopyingProgress.Text = progress; }));
this.Refresh();
}
private void handlerThread2ProgressEvent(string progress) {
lblCopyingProgress.Invoke(new MethodInvoker(delegate { lblCopyingProgress.Text = progress; }));
this.Refresh();
}
}