【发布时间】:2011-07-16 16:09:57
【问题描述】:
使用 C#、WCF、WPF 的客户端/服务器桌面应用程序。由于几乎每个操作都需要访问服务器(列表/创建/保存/删除/等),因此每个操作都有可能冻结整个 UI。下面是一个调用service.GetAll() 的简单实现示例,这可能需要“很长时间”(超过几百毫秒):
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
vm.Users.Clear();
foreach (var user in service.GetAllUsers())
vm.Users.Add(user);
}
(旁白:我很想知道为什么List 有AddRange 而ObservableCollection 没有。)
BackgroundWorker 救援:
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
var worker = new BackgroundWorker();
worker.DoWork += (s, e) =>
{
Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = false; });
e.Result = service.GetAllUsers();
};
worker.RunWorkerCompleted += (s, e) =>
{
vm.Users.Clear();
foreach (var user in (List<UserDto>)e.Result)
vm.Users.Add(user);
Dispatcher.BeginInvoke((Action)delegate() { btnRefresh.IsEnabled = true; });
};
worker.RunWorkerAsync();
}
(顺便说一句:上面的代码已被简化,但这就是它的要点。)
使用BackgroundWorker 的代码完全符合我的要求。该应用程序始终保持响应状态,并且该按钮在通话期间被禁用。但是,这意味着在用户可能执行的每个可能操作中添加 15 行。
说不是这样。
【问题讨论】:
-
请确保您确实希望应用程序在这些调用期间响应。有些调用应该阻塞整个应用程序,有些调用可能会更宽松。
-
等下一个版本的VS出来吧:msdn.microsoft.com/en-us/vstudio/async.aspx
-
@Robaticus 同意。 @John 如果可以的话。 :)
标签: c# wpf wcf backgroundworker