0

我有一个程序通过 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");
        }

    }        
4

3 回答 3

1

尽管您创建 aBackgroundWorker的目的是在后台线程上执行长时间运行的任务,但您仍在将所有处理分派回 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;
    }));
}
于 2012-05-08T18:04:23.257 回答
1

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

如果您通过 DataBinding 使用INotifyPropertyChange,则完全放弃Dispatcher.Invoke,因为对 UI 线程的更改是自动完成的。

于 2012-05-08T18:04:40.487 回答
0

尝试

Dispatcher.BeginInvoke(...)
于 2012-05-08T20:45:01.503 回答