首页 > 代码库 > 如何实现异步调用WCF

如何实现异步调用WCF

在面向服务的.NET开发中,我们经常要调用WCF服务加载数据,这时候,如果使用同步调用,会阻止UI,影响用户体验UE/UX,而且当服务器ping不通或者网速特别烂的情况下,这时候基本上是处于卡死状态,令人难以接受。

因此,实现一步调用WCF是.NET开发中一个必须的步骤。下面介绍如何实现一步调用WCF。

第一步:在WCF端建立一个WCF服务:WcfService,建立一个接口SumByTwoNumber,返回相加结果int;

 

第二步:在WPF端引用该WCF服务并实例化:

WcfService.WcfServiceClient client = new WcfService.WcfServiceClient();

 

第三步:你可以使用定义代理来实施异步调用,或者使用匿名代理。这里我们用定义代理

     创建delegate对象,并将你想要传递的函数作为参数传入。 
     创建代理对象的方法:
         1). MyDelegate myDelegate = new MyDelegate(实例名.方法名);
         2). MyDelegate myDelegate = new MyDelegate(类名.方法名);
     注:

     如果需要代理的方法是一个static静态方法的话,采用第2种方式,否则采用第1种方式。
     这里我们使用静态方法,免去创建实例的过程。

 

第四步:就是执行异步调用并获得返回值了,用myDelegate的BeginInvoke

     获得数据的方法是执行myDelegate.EndInvoke,它的返回值就是在我们的WCF服务接口返回的数据。

     注:
     A. 这个EndInvoke一定要保证在BeginInvoke的callBack里调用,因为只有在服务接口执行完了才会有数据;

     B. 取得数据后如果要操作WPF的UI,不能直接在callBack里操作,因为callBack执行的时候已经不是和UI在同一个线程了,要用UI线程的话,需要使用Dispatcher.BeginInvoke()..

以下是完整代码:

 

    public partial class MainWindow : Window
    {
        public delegate int MyDelegate(int num1, int num2);
        MyDelegate myDelegate = new MyDelegate(MainWindow.AsynchronousCall);
 
        public MainWindow()
        {
            InitializeComponent();
        }
 
        private static int AsynchronousCall(int num1, int num2)
        {
 
            try
            {
                WcfService.WcfServiceClient client = new WcfService.WcfServiceClient();
                return client.SumByTwoNumber(num1, num2);
            }
            catch
            {
                return -1;
            }
        }
 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            IAsyncResult result = myDelegate.BeginInvoke(1, 3, (res) =>
            {
                int sum = myDelegate.EndInvoke(res);
                if (sum == -1)
                {
                    MessageBox.Show("无法连接服务器!");
                    CloseWating();
                    return;
                }
                Show("结果为", sum.ToString());
            }, null);
            this.label.Content = null;
            ShowWating();
        }
 
        void Show(params string[] str)
        {
            this.Dispatcher.BeginInvoke(
                new Action(() =>
                {
                    StringBuilder sb = new StringBuilder();
                    str.ToList().ForEach(s => sb.Append(s));
 
                    this.label.Content = new TextBlock() { Text = sb.ToString() };
                    CloseWating();
                })
            );
        }
 
        private void ShowWating()
        {
            //显示等待条
        }
 
        private void CloseWating()
        {
            //关闭等待条
        }
    }
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

参考来源:http://www.cnblogs.com/itelite/archive/2011/12/13/2286647.html

这个来源写的是使用匿名代理方法,有些童鞋可能还不是特别熟悉,因此我就用常规的定义代理方法写了。

O(∩_∩)O~