在我维护的Silverlight 4.0(带Prism)应用程序中,页面有一个Search按钮,它根据用户输入的搜索条件异步调用WCF服务从数据库中获取一些数据。在搜索操作期间(即从点击搜索按钮到页面上显示时间搜索结果的时间),页面顶部显示进度条窗口(Silverlight子窗口)(我知道它会阻止用户持续时间) ,但这就是应用程序的所有页面都是如何设计的,我无法改变它。有时,搜索操作需要很长时间(几分钟)才能返回并显示数据,有时它会非常快速地显示结果,具体取决于搜索条件。现在,如果用户觉得花费太多时间来显示结果,他们希望能够灵活地取消任何搜索操作。
为了满足这一要求,我尝试了以下方法:
1)在进度条窗口中添加了取消搜索按钮
2)在进度条的ViewModel中添加了一个公共静态布尔变量(取消搜索标志,默认值为false)。
3)在同一视图模型中的取消搜索按钮的单击命令处理程序中,将取消搜索标志设置为true,然后关闭进度条窗口。
4)在异步WCF Serach Service的回调方法中,首先检查进度条的取消搜索标志是否为真。如果是,请忽略结果(不要做任何事情)。否则,像往常一样将返回的结果绑定到UI。
但是,在测试“取消搜索”按钮时,我发现在“取消”按钮的单击命令处理程序之前调用了WCF回调方法,因此即使单击“取消搜索”按钮,搜索结果也会显示。显然,对于在用户单击“取消”按钮之前执行并完成的短期运行WCF调用,会发生这种情况。对于长时间运行的WCF调用(获取结果需要几分钟),上述解决方案可能正常工作。但是在点击搜索按钮时,我无论如何都不知道它是短暂的异步调用还是长时间运行,是吗?那么是否有可能以这种方式满足要求或使用其他方式?也许同步WCF调用(但我再次收集它对Silverlight来说是一个很大的禁忌?
答案 0 :(得分:1)
当您从WCF订阅任何异步操作时,WCf会将响应发送回处理程序并返回结果。 在您的情况下,您有一个搜索按钮,它与WCF会谈结果,但是如果等待时间更长,您需要一种机制来中断操作。
当您单击取消按钮时,您尝试取消订阅该事件,以便您指示不听取回调而不会产生任何结果。这可以通过使用 - =运算符和你的回调处理程序来实现。
希望这有帮助。
答案 1 :(得分:0)
为Cancel命令添加CanExecuteCancelCommand,用于检查布尔变量。当您启动对WCF服务的调用时,将此变量设置为true并调用该命令的RaiseCanExecuteChanged方法。同样,只要WCF服务返回,就将该属性设置为false并再次调用RaiseCanExecuteChanged方法。
这允许用户仅在等待服务返回其结果时单击该按钮。
这样的事情:
private bool _canCancelWCFService = false;
DelegateCommand _WCFCommand;
void Method()
{
_WCFCommand = new DelegateCommand(ExecuteWCFService, CanExecuteWCFService);
}
private bool CanExecuteWCFService()
{
return _canCancelWCFService;
}
private void ExecuteWCFService()
{
_canCancelWCFService = true;
_WCFCommand.RaiseCanExecuteChanged();
_wcfService.Completed += new EventHandler<CompletedEventArgs>(CompletedCallback);
//make WCF call here
_wcfService.DoSomething();
}
static void CompletedCallback(object sender, CompletedEventArgs e)
{
_canCancelWCFServiceCall = false;
_WCFCommand.RaiseCanExecuteChanged();
//Process results here...
}