使用 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 程序也可以用。