如何在WPF中处理长时间运行的“线程”?

5

晚上好!

目前我正在开发一个用于某些REST服务的WPF客户端。与REST服务的通信没有问题,并且在一个额外的程序集(通信接口)中完成。

基本上:
我有一个“搜索”按钮,执行一个方法。该方法与服务进行通信,更新一些文本框和进度条(为了向用户提供一些图形信息,以显示我们的进度...)。 不幸的是,托管服务的服务器有点慢,导致响应时间严重延迟(大约4秒)。反过来,这会导致我的WPF应用程序等待,最终导致:变黑,标题为“未响应”...

我已经尝试将此执行放入另一个线程中,但是...很明显我将无法访问我的WPF窗口的控件...

目前我真的很无助...有人能给我一些处理例程或解决方案吗?

2个回答

7
您的UI线程正忙于等待Web服务的响应,因此无法绘制屏幕。一个好的选择是将服务请求推到另一个非UI线程上。可以研究一下BackgroundWorker,它专门设计用于简化这个过程。它处理从非UI线程到UI线程的跨线程调用的封送。
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync(arg);
...

static void bw_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = (BackgroundWorker)sender;
    int arg = (int)e.Argument;
    e.Result = CallWebService(arg, e);
}

static void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar.Increment();
}

static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    label.Text = "Done: " + e.Result.ToString();
}

这基本上是我尝试的,但我得到了“调用线程无法访问此对象,因为不同的线程拥有它”的错误。 - user57508
1
代码?此外,请确保您不要从doWork事件处理程序中触摸UI。 - Michael Petrotta
或者任何被它调用的东西(在同一个非 UI 线程上运行)。 - Michael Petrotta
于是我就这样做了...谢谢你的解决方案,但我更喜欢调度程序变体! - user57508

0

要从第二个线程访问您的控件,请使用Dispatcher.BeginInvoke:

Dispatcher.BeginInvoke(new Action(() =>
    {
        // Update your controls here.
    }), null);

或者你可以考虑使用BackgroundWorker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接