您的位置:首页 > 产品设计 > UI/UE

WPF 异步执行方法后对 UI 进行更新的几种方法

2015-01-03 00:00 176 查看
摘要: WPF 中异步执行任务后对 UI 进行更新需要在 UI 线程内进行

使用 async/await 的情况:

private async void Button_Click(object sender, RoutedEventArgs e)
{
(sender as Button).IsEnabled = false;
const string do7zCmd = @"a D:\x7zaTest.7z"
+ @" E:\WpfApp1\WpfApp1\bin\Debug\*.dll"
+ @" E:\WpfApp1\WpfApp1\bin\Debug\*.xml"
;

tex1.Text = "Running...";
tex1.Focus();

var ret = await Task.Run(() => X7za.Do7z(do7zCmd));

//更新UI线程的操作
tex1.Text += "\r\n" + ret + "\r\n" + do7zCmd;
(sender as Button).IsEnabled = true;
}

在不使用 async/await 的情况下有 3 种办法:

private void Button_Click(object sender, RoutedEventArgs e)
{
(sender as Button).IsEnabled = false;
const string do7zCmd = @"a D:\x7zaTest.7z"
+ @" E:\WpfApp1\WpfApp1\bin\Debug\*.dll"
+ @" E:\WpfApp1\WpfApp1\bin\Debug\*.xml"
;

//更新UI线程的操作
var f = new Action<int>(ret =>
{
tex1.Text += "\r\n" + ret + "\r\n" + do7zCmd;
(sender as Button).IsEnabled = true;
});

//1.BackgroundWorker - 推荐,有进度报告机制,对 UI 的操作在创建线程内
var b = new BackgroundWorker();
b.DoWork += (o, args) => args.Result = X7za.Do7z(do7zCmd);
b.RunWorkerCompleted += (o, args) => f((int)args.Result);
b.RunWorkerAsync();

//2.委托异步执行 - 主要就是下面的 BeginInvoke 调用,
//这是从 BackgroundWorker 的源码里挖出来的用法。
//
//这个片段对 UI 线程的操作是在别的线程通过 WPF
//Application 对象的 Dispatcher 机制跨线程执行的。
new Action(() =>
{
var ret = X7za.Do7z(do7zCmd);
Application.Current.Dispatcher.Invoke(() => f(ret));
}).BeginInvoke(null, null);

//3.Task.Run - 很通俗的方法了。对 UI 的操作跟片段2一样。
Task.Run(() =>
{
var ret = X7za.Do7z(do7zCmd);
Application.Current.Dispatcher.Invoke(() => f(ret));
});

tex1.Text = "Running...";
tex1.Focus();
}

就是酱紫。
推荐第一种,WinForm 程序也可以用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C# WPF 异步 UI