从WinRT中的线程更新UI [英] Update UI from thread in WinRT

查看:63
本文介绍了从WinRT中的线程更新UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从几天前发布Windows 8客户预览版以来,我正在使用C#开发新的WinRT(用于Metro应用程序),并且已经将自己编写的IRC类移植到了新的线程和网络中。

Since the Windows 8 consumer preview was released a few days ago, I am working on the new WinRT (for Metro Applications) in C# and I had ported my self written IRC class to the new threading and networking.

问题是:我的课程正在运行一个线程,用于接收来自服务器的消息。如果发生这种情况,线程将进行一些解析,然后触发一个事件以通知应用程序有关此情况。然后,已订阅的函数应该更新UI(一个文本块)。

The problem is: My class is running an thread for receiving messages from the server. If this happens, the thread is making some parsing and then firing an event to inform the application about this. The subscribed function then 'should' update the UI (an textblock).

这是问题所在,线程无法更新UI和已使用过的调用者方法。 NET 4.0似乎不再可行。是否有新的解决方法,甚至是更新UI的更好方法?如果我尝试从事件订阅者更新UI,我将得到以下 Exception

This is the problem, the thread cannot update the UI and the invoker method that has worked with .NET 4.0 doesn't seem to be possible anymore. Is there an new workaround for this or even an better way to update the UI ? If I try to update the UI from the event subscriber i will get this Exception:


该应用程序调用了一个已为
不同线程编组的接口(HRESULT异常:0x8001010E
(RPC_E_WRONG_THREAD))

The application called an interface that was marshalled for a different thread (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))


推荐答案

在WinRT(通常是C#5)中处理此问题的首选方法是使用 async -等待

The preferred way to deal with this in WinRT (and C# 5 in general) is to use async-await:

private async void Button_Click(object sender, RoutedEventArgs e)
{
    string text = await Task.Run(() => Compute());
    this.TextBlock.Text = text;
}

在这里, Compute()方法将在后台线程上运行,完成后,该方法的其余部分将在UI线程上执行。同时,UI线程可以随意执行所需的任何操作(例如处理其他事件)。

Here, the Compute() method will run on a background thread and when it finishes, the rest of the method will execute on the UI thread. In the meantime, the UI thread is free to do whatever it needs (like processing other events).

但是,如果您不想或不能使用 async ,您可以使用 Dispatcher ,其方式与WPF类似(尽管不同):

But if you don't want to or can't use async, you can use Dispatcher, in a similar (although different) way as in WPF:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Task.Run(() => Compute());
}

private void Compute()
{
    // perform computation here

    Dispatcher.Invoke(CoreDispatcherPriority.Normal, ShowText, this, resultString);
}

private void ShowText(object sender, InvokedHandlerArgs e)
{
    this.TextBlock.Text = (string)e.Context;
}

这篇关于从WinRT中的线程更新UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆