WPF调用WCF不支持异步,但是在加载数据的时候阻止UI是很影响UX的。这里自己实现了一下异步调用:
WCF部分的接口实现就不讨论了,建立一个普通的返回数据的服务即可。
这里我 建一个WCF服务:CoreService, 建立一个接口(GetUserInfoByAliasAndPassword)
返回用户信息(UserInfo)
1. 首先在WPF客户端实例化一个服务:
CoreService.CoreServiceClient client = new CoreService.CoreServiceClient();
2. 然后在需要调用服务端地方开始实施异步调用,为了可以拿到返回值,我用的是Func
Func myFunc = new Func
(delegate(string s1, string s2){...调用wcf服务接口并返回...});
或
Func myFunc = new Func
((string s1, string s2) =>{...调用wcf服务接口并返回...});
这里用的方法比较懒,不想再去定义代理了就用了匿名的 呵呵
3. 接下来就是执行异步调用并拿到返回值了,用Func的BeginInvoke
myFunc.BeginInvoke("arg1", "arg2", callBack, object);
拿数据的方法是执行myFunc.EndInvoke,它的返回值就是在我们的WCF服务接口返回的数据了,这个数据的类型当然是我们在定义Func时定义好的
类型了 呵呵
有两点要注意:
A. 这个EndInvoke一定要保证在BeginInvoke的callBack里调用呀 这个大家应该都明白,等服务接口执行完了才有数据可以拿呀 呵呵
B. 拿回来数据后如果要操作WPF的UI,可别在callBack里直接搞啊,因为callBack执行的时候已经不是和UI在同一个线程了,要用UI线程的
Dispatcher.BeginInvoke()..
以下是完整代码:
public MainWindow()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//Func定义 参数:用户名,密码, 返回值
Func<string, string, UserInfo> myFunc = new Func<string, string, UserInfo>(delegate(string s1, string s2)
//Func myFunc = new Func((string s1, string s2) =>
{
//调用wcf服务接口并返回
CoreService.CoreServiceClient client = new CoreService.CoreServiceClient();
UserInfo ui = client.GetUserInfoByAliasAndPassword(s1, s2);
return ui;
});
IAsyncResult result = myFunc.BeginInvoke("jing", "123", (res) =>
{
UserInfo user = myFunc.EndInvoke(res);
show(">> ", user.Alias.ToString(), user.Name);
}, null);
}
void show(params string[] str)
{
this.Dispatcher.BeginInvoke(
new Action(() =>
{
StringBuilder sb = new StringBuilder();
str.ToList().ForEach(s => sb.Append(s + ", "));
this.Content = new TextBlock() { Text = sb.ToString().Substring(0, sb.ToString().Length - 2) };
})
);
}