我希望通过线程控制一些UI元素,而其他线程则通过WP8中的不同线程控制。 有没有办法让Muulti UI线程像这样?帮助我。
答案 0 :(得分:3)
为了从多个线程更新UI,您可以使用Dispatcher
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
// Code to modify your UI
}
答案 1 :(得分:0)
正如我在评论中所述,我认为你以错误的方式思考问题。你想要的实际上并不是拥有多个GUI线程,你只想在其他线程上完成工作。让我用一些伪代码(未经测试)来说明这一点:
// API method with Thread.Sleep as requested
public static int GetAnswer() {
Thread.Sleep(5000);
return 42;
}
// Code assumes to be inside some kind of "Window" class where there is a Dispatcher
public void SomeButton_OnClick(object sender, EventArgs e) {
Task.Run(() => {
int answer = GetAnswer();
Dispatcher.BeginInvoke(() => {
MyLabel.Text = answer;
});
});
}
现在解释:
这里发生的是有一些按钮,点击时调用一个需要很长时间(5秒)的方法(GetAnswer
)。如果在GUI线程上调用该方法,GUI将挂起5秒钟(这不是一件好事),所以我们要做的是在另一个线程上调用GetAnswer
(使用Task.Run
,其他可能的方式要做到这一点是手动排队线程池,但Task.Run
有一个简单的名称,当你没有Visual Studio方便帮助你时更容易记住。调用Task.Run
创建的线程然后开始处理答案,并在5秒后完成。但是,由于它在后台线程上运行,因此无法更新GUI,因此(在Dispatcher
的帮助下)它告诉GUI线程更新{的文本{1}}第一次机会。
这将使您能够调用慢速方法(因为它们执行CPU绑定工作,或者它们休眠),然后在GUI中使用结果。
<强> [编辑] 强>
我读了你关于从互联网上加载内容的评论,你可能想要检查的是使用异步API而不是同步API。因此,您可以编写这样的代码,而不会阻止UI:
MyLabel
请注意,为了使用异步方法,您的API需要支持它。或者您可以简化我在上一个示例中发布的代码:
public async void SomeButton_OnClick(object sender, EventArgs e) {
// Because we use await here, the GUI thread will not be blocked
var data = await DownloadFromSomewhereAsync();
// Once the resource is done downloaded, the rest of the method will run on the UI thread
MyLabel.Text = data;
}
这是因为// API method with Thread.Sleep as requested
public static int GetAnswer() {
Thread.Sleep(5000);
return 42;
}
public async void SomeButton_OnClick(object sender, EventArgs e) {
int answer;
await Task.Run(() => {
answer = GetAnswer();
});
MyLabel.Text = answer;
}
会返回可以等待的Task.Run
。