我有主程序
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Worker w1 = new Worker(1);
Worker w2 = new Worker(2);
Thread w1Thread = new Thread(new ThreadStart(w1.StartWorking));
Thread w2Thread = new Thread(new ThreadStart(w2.StartWorking));
w1Thread.Start();
w2Thread.Start();
Application.Run(new MainWindow());
if (w1Thread.IsAlive)
{
w1Thread.Abort();
}
if (w2Thread.IsAlive)
{
w2Thread.Abort();
}
}
}
和工人阶级:
class Worker
{
public int m_workerId;
public bool m_workerLifeBit;
public bool m_workerWork;
public Worker(int id)
{
m_workerId = id;
m_workerLifeBit = false;
}
public void StartWorking()
{
while (!m_workerWork)
{
m_workerLifeBit = false;
System.Threading.Thread.Sleep(5000);
m_workerLifeBit = true;
System.Threading.Thread.Sleep(5000);
}
}
}
我checkBox
表格MainWindow
。
如何监控Worker
变量m_workerLifeBit
的状态并在MainWindow
checkBox
中显示其变化?
我发现这个q& a How to update the GUI from another thread in C#? hovewer答案没有显示完整的示例,我使用线程安全委托失败了。
我想要在Worker.StartWorking
中触发一些事件机制并以MainWindow
形式捕获插槽。
答案 0 :(得分:2)
如评论中所述,如果这是 WinForms 应用程序,那么我建议使用BackgroundWorker。
开始bg工作者并订阅活动:
BackgroundWorker worker = new BackgroundWorker();
// Subscribing to the worker method. Do all of your work here
worker.DoWork += worker_DoWork;
// Subscribing to the progress changed event where you'll want to update the UI
worker.ReportProgress = true;
worker.ProgressChanged += worker_ProgressChanged;
// Subscribing to the worker completed event. Fires when the work is complete
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
// This line starts the worker
worker.RunWorkerAsync();
然后您可以将您的方法定义为:
void worker_DoWork(object sender, DoWorkEventArgs e)
{
// Perform some work with the object you've passed in e.g.
MyObj foo = (MyObj)e.Argument;
foo.Name = "foobar";
// Notify UI
worker.ReportProgress(100, foo);
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Update UI
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// Worker has finished
}
答案 1 :(得分:1)
以下是使用events的简单版本:
class Worker
{
public event Action<bool> WorkerLifeBitChanged;
// ...
public void StartWorking()
{
// ...
m_workerLifeBit = false;
OnWorkerLifeBitChanged();
// ...
private void OnWorkerLifeBitChanged()
{
if (WorkerLifeBitChanged != null)
WorkerLifeBitChanged(m_workerLifeBit);
}
然后在Main
:
//...
var mainWindow = new MainWindow();
w1.WorkerLifeBitChanged += mainWindow.UpdateWorkerLifeBit;
w2.WorkerLifeBitChanged += mainWindow.UpdateWorkerLifeBit;
w1Thread.Start();
w2Thread.Start();
Application.Run(mainWindow);
//...
UpdateWorkerLifeBit
中的MainWindow
实施:
public void UpdateWorkerLifeBit(bool workerLifeBit)
{
if (this.checkBox.InvokeRequired)
{
this.Invoke(new Action(() => checkBox.Checked = workerLifeBit));
}
else
{
checkBox.Checked = workerLifeBit;
}
}
答案 2 :(得分:0)
一种解决方案是将Program类的引用(或者甚至是程序类中的委托,或者worker类中的数据引用)传递给Worker线程。您可以直接从线程代码调用程序的函数。您也可以使用信号,但对于这个小例子,我之前的“解决方案”是可以接受的。