首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# XAML GUI因应用编程接口函数而冻结

C# XAML GUI因应用编程接口函数而冻结
EN

Stack Overflow用户
提问于 2012-05-09 01:52:40
回答 3查看 255关注 0票数 0

我有一个程序,有股票行情推送到我通过一个API。该程序还有一个用XAML制作的前端,它在程序运行时冻结(即处理API发送给我的信息)。我尝试过使用Dispatcher.Invoke和/或BackgroundWorker,并且阅读了大量关于线程的知识,但无法将其解冻。也许我只是做错了什么。我在这里附上了相关的代码。希望有人能帮上忙。

代码语言:javascript
复制
    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");
        }

    }        
EN

回答 3

Stack Overflow用户

发布于 2012-05-09 02:04:23

尽管您创建BackgroundWorker的目的是在后台线程上执行长时间运行的任务,但您仍然将所有处理分派回UI线程。

代码语言:javascript
复制
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。

例如:

代码语言:javascript
复制
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;
    }));
}
票数 1
EN

Stack Overflow用户

发布于 2012-05-09 02:04:40

是的,你做错了什么。计算应该在线程中单独完成,添加,只有UI更改应该在Dispatcher.Invoke中完成。

如果通过INotifyPropertyChange使用DataBinding,则完全删除Dispatcher.Invoke,因为将更改编组到UI线程是自动完成的。

票数 1
EN

Stack Overflow用户

发布于 2012-05-09 04:45:02

试一试

代码语言:javascript
复制
Dispatcher.BeginInvoke(...)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10503812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档