C# XAML GUI 由于 API 函数而冻结
本文关键字:函数 冻结 API 由于 XAML GUI | 更新日期: 2023-09-27 18:33:36
我有一个程序,它通过API将股票报价推送给我。该程序还有一个用 XAML 制作的前端,当该程序运行时冻结(即处理 API 发送给我的信息)。我尝试使用Dispatcher.Invoke和/或BackgroundWorker 并且已经阅读了大量线程,但无法将其解冻。也许我只是做错了什么。我在这里附上了相关代码。希望有人能帮忙。
private void QuoteUpdate(QuoteInfo info)
{
BackgroundWorker bwQuoteUpdate = new BackgroundWorker();
bwQuoteUpdate = new BackgroundWorker();
bwQuoteUpdate.WorkerSupportsCancellation = true;
bwQuoteUpdate.DoWork += bwQuoteUpdate_DoWork;
bwQuoteUpdate.RunWorkerAsync(info);
}
private void bwQuoteUpdate_DoWork(object sender, DoWorkEventArgs e)
{
try
{
Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(() =>
{
QuoteInfo info = e.Argument as QuoteInfo;
//logical functions and work are here
}));
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("Error in QuoteUpdate: " + ex.Message, "Exception Thrown");
}
}
尽管您正在创建一个旨在在后台线程上执行长时间运行的任务的BackgroundWorker
,但仍会将所有处理调度回 UI 线程。
private void bwQuoteUpdate_DoWork(object sender, DoWorkEventArgs e)
{
// Code here runs on background thread.
Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(() =>
{
// Code here runs on UI thread.
}));
}
您需要做的是首先在后台线程上执行计算,但不更新任何 UI 组件;而是将所有结果存储在局部变量中。然后,完成后,使用 Dispatcher.Invoke
将控件调度回 UI 线程,并使用存储在局部变量中的结果来更新 UI。
例如:
private void bwQuoteUpdate_DoWork(object sender, DoWorkEventArgs e)
{
// Code here runs on background thread.
QuoteInfo info = e.Argument as QuoteInfo;
string result = PerformLongRunningProcessing(info);
Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(() =>
{
// Code here runs on UI thread.
this.resultTextBox.Text = result;
}));
}
是的,你做错了什么。计算应该单独在线程中完成,只添加 UI 更改应该在Dispatcher.Invoke
中完成。
如果通过 INotifyPropertyChange
使用数据绑定,则完全删除Dispatcher.Invoke
,因为封送对 UI 线程的更改是自动完成的。
试试
Dispatcher.BeginInvoke(...)