我正在构建一个应用程序,它不断地从设备中提取数据并更新到UI。
一旦我点击一个开始按钮,一个子线程被创建,里面有一个while循环,每200ms从设备读取数据,然后我调用调度程序。
将此值更新到GUI。while(true)
{
if (!IsPowerOn)
{
Console.WriteLine("background thread else exit");
break;
}
else
{
try
{
if (session.IsDisposed || session == null) break;
session.RawIO.Write("MEAS:VOLT?r");
var volt = session.RawIO.ReadString();
Dispatcher.Invoke(() => VoltOutput = float.Parse(volt));
Console.WriteLine(volt);
if (session.IsDisposed || session == null) break;
session.RawIO.Write("MEAS:CURR?r");
var curr = session.RawIO.ReadString();
Console.WriteLine(curr);
Action<string> action1 = delegate (string s) { CurrOutput = float.Parse(s); };
Dispatcher.Invoke(action1, curr);
Thread.Sleep(200);
Console.WriteLine("sleep");
}
catch (Exception)
{
session.Clear();
Console.WriteLine("background thread except exit");
break;
}
}
}
在主线程中,如果我点击Stop按钮,IsPower = false;thread.join ();被称为。但这将导致程序卡住。似乎调度员被困在这里了。不知道调度程序是被非正常终止还是仍在工作。无论哪种方式,主线程都没有响应thread.join.
希望有人能给我一些提示,或者像这样的应用程序的常见做法
感谢看起来像是死锁。在bg线程中,您期望GUI线程处理Dispatcher.Invoke
,但GUI线程在Button.Click
通过thread.join()
的事件处理程序中被阻塞。
避免
- fire&forget
Dispatcher.InvokeAsync
或使事件处理程序 - 或者不调用
thread.join()
/不等待线程完成。你可以在程序逻辑的其他部分检查线程状态,以确保线程已经完成。
Button.Click
async
并调用await Task.Run(()=>{thread.join();});
我不知道数据抓取有多快,但为了使停止更灵敏,你可以尝试在(session.IsDisposed || session == null)
和Thread.Sleep
之前添加IsPowerOn
的检查。