Silverlight同步(Synchronous)调用WCF服务

  Silverlight的RIA应用中访问远端的WebService或WCF服务,都是通过异步线程模式调用的。在某些情况下我们的调用是需要同步进行,虽然Silverlight没有内置同步线程模式调用远端服务接口,但是我们可以通过多线程的处理来伪装出同步调用的实现。在.NET Framework的多线程编程中提供了丰富的线程接口,其中AutoResetEvent和ManualResetEvent在多线程编码中最为常用,本文将介绍如何通过AutoResetEvent的线程等待特性实现Silverlight同步调用远端WCF服务。

  一、定义WCF服务

  为了演示同步调用WCF服务的实现,提供一个简单的WCF服务接口,完成返回一本图书基本信息,WCF服务接口定义如下:

[ServiceContract]

public interface IDataService

{

    [OperationContract]

    Book GetBook();

}

public class Book

{

    public int ID { get; set; }

    public string Name { get; set; }

    public string Author { get; set; }

    public double Price { get; set; }

}

  接口提供一个返回图书基本信息的方法,包括图书编好,图书名,图书作者以及图书价格。接口具体的实现如下代码:

public class DataService : IDataService

{

    public Book GetBook()

    {

        return new Book

        {

            ID = 1001,

            Name = "《三国演义》",

            Author = "罗贯中",

            Price = 89.50

        };

    }

}

  如上提供可正常运行的WCF服务接口,在需要调用接口的地方通过WEB引用既可生成该服务的客户端代理对象。

  二、基于MVVM模式的视图模型

  MVVM模式的核心为INotifyPropertyChanged接口,对于实体模型对象和UI控件元素间提供了完善的同步更新特性。为了方便界面元素同步更新,这里引入了MVVP模式的简单应用。

public class ViewModelBase : INotifyPropertyChanged

{

    public event PropertyChangedEventHandler PropertyChanged;

protected void RaisePropertyChangedEvent(string propertyName)

    {

        var handler = PropertyChanged;

        if (handler != null)

            handler(this, new PropertyChangedEventArgs(propertyName));

    }

}

  还需要对应于服务接口中的Book对象定义一个ViewModel对象,详细如下代码所示:

public class BookViewModel : ViewModelBase

{

    private int iD;

    /// <summary>

    /// 图书ID

    /// </summary>

    public int ID

    {

        get { return iD; }

        set

        {

            iD = value;

            RaisePropertyChangedEvent("ID");

        }

    }

private string name;

    /// <summary>

    /// 图书名称

    /// </summary>

    public string Name

    {

        get { return name; }

        set

        {

            name = value;

            RaisePropertyChangedEvent("Name");

        }

    }

private string author;

    /// <summary>

    /// 图书作者

    /// </summary>

    public string Author

    {

        get { return author; }

        set

        {

            author = value;

            RaisePropertyChangedEvent("Author");

        }

    }

private double price;

    /// <summary>

    /// 图书价格

    /// </summary>

    public double Price

    {

        get { return price; }

        set

        {

            price = value;

            RaisePropertyChangedEvent("Price");

        }

    }

}

三、基于AutoResetEvent的同步实现

  利用AutoResetEvent的线程等待特性,可以折中实现Silverlight同步调用远端WCF服务。其原理就是在Silverlight发起异步调用远端WCF的时候进行线程阻塞,比记录异步调用远端WCF服务接口的完成事件,当异步调用完成后就终止线程阻塞,从而获取状态事件对象中或得调用远程接口所返回的结果。由于视图模型对象实现了INotifyPropertyChanged接口能够及时的更新界面元素,以此间接的就实现了同步方式调用。

public class AsyncCall
Status<T>

{

    public AsyncCallStatus()

    {

}

public T CompletedEventArgs { get; set; }

}public class BookFacade

{

    private AutoResetEvent autoResetEvent = new AutoResetEvent(false);

public void GetBook(BookViewModel viewModel)

    {

        if (viewModel == null)

        {

            throw new ArgumentNullException("viewModel", "参数不能为空。");

        }

DataService.DataService
Client client = new DataService.DataServiceClient();

        client.GetBookCompleted += client_GetBookCompleted;

var status = new AsyncCallStatus<GetBookCompletedEventArgs>();

        client.GetBookAsync(status);

        //阻塞线程

        autoResetEvent.WaitOne();

if (status.CompletedEventArgs.Error != null)

        {

            throw status.CompletedEventArgs.Error;

        }

        var book = status.CompletedEventArgs.Result;

        viewModel.ID = book.ID;

        viewModel.Name = book.Name;

        viewModel.Author = book.Author;

        viewModel.Price = book.Price;

    }

private void client_GetBookCompleted(object sender, GetBookCompletedEventArgs e)

    {

        var status = e.UserState as AsyncCallStatus<GetBookCompletedEventArgs>;

status.CompletedEventArgs = e;

        //终止线程阻塞

        autoResetEvent.Set();

    }

}

  四、Silverlight前端调用

  Siverlight前端就简单布局一个表单作为数据呈现界面,其代码如下:

<Grid x:Name="LayoutRoot" Background="White">

    <Grid HorizontalAlignment="Left" Name="grid1" VerticalAlignment="Top" W
idth="300" Margin="20">

        <Grid.RowDefinitions>

            <RowDefinition Height="30"></RowDefinition>

            <RowDefinition Height="30"></RowDefinition>

            <RowDefinition Height="30"></RowDefinition>

            <RowDefinition Height="30"></RowDefinition>

            <RowDefinition Height="30"></RowDefinition>

        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>

            <ColumnDefinition Width="60"></ColumnDefinition>

            <ColumnDefinition Width="*"></ColumnDefinition>

        </Grid.ColumnDefinitions>

        <sdk:Label  HorizontalAlignment="Left" Content="图书编号:" VerticalAlignment="Center" Grid.Column="0" Grid.Row="0"/>

        <TextBox Text="{Binding ID}" Grid.Column="1" Grid.Row="0"></TextBox>

        <sdk:Label  HorizontalAlignment="Left" Content="图书名称:" VerticalAlignment="Center" Grid.Column="0" Grid.Row="1"/>

        <TextBox Text="{Binding Name}" Grid.Column="1" Grid.Row="1"></TextBox>

        <sdk:Label  HorizontalAlignment="Left" Content="图书作者:" VerticalAlignment="Center" Grid.Column="0" Grid.Row="2"/>

        <TextBox Text="{Binding Author}" Grid.Column="1" Grid.Row="2"></TextBox>

        <sdk:Label  HorizontalAlignment="Left" Content="图书价格:" VerticalAlignment="Center" Grid.Column="0&quo

时间: 2024-12-09 14:23:47

Silverlight同步(Synchronous)调用WCF服务的相关文章

一起谈.NET技术,Silverlight同步(Synchronous)调用WCF服务

Silverlight的RIA应用中访问远端的WebService或WCF服务,都是通过异步线程模式调用的.在某些情况下我们的调用是需要同步进行,虽然Silverlight没有内置同步线程模式调用远端服务接口,但是我们可以通过多线程的处理来伪装出同步调用的实现.在.NET Framework的多线程编程中提供了丰富的线程接口,其中AutoResetEvent和ManualResetEvent在多线程编码中最为常用,本文将介绍如何通过AutoResetEvent的线程等待特性实现Silverlig

Silverlight中异步调用WCF服务,传入回调函数

以前学的ASP.NET,调用的都是同步方法,同步方法的好处就是,一步一步走,完成这步才会走下一步.然而,WCF使用的都是异步方法,调用之后不管有没有获得结果就直接往下走,最可恶的是异步函数都是Void类型,得不到返回结果,虽然有Completed的事件处理,但是还是感觉比较束缚,无法与前端交互. 这里就跟大家分享一种传入回调函数的方法,把前台的方法写好,传到后台,让异步方法调用完成时执行.废话不多说了,开始写代码: 首先,要先建一个带网站的sliverlight项目,这里就不细说了,在网站中添加

Silverlight同步(Synchro“.NET研究”nous)调用WCF服务

Silverlight的RIA应用中访问远端的WebService或WCF服务,都是通过异步线程模式调用的.在某些情况下我们的调用是需要同步进行,虽然Silverlight没有内置同步线程模式调用远端服务接口,但是我们可以通过多线程的处理来伪装出同步调用的实现.在.NET Framework的多线程编程中提供了丰富的线程接口,其中AutoResetEvent和ManualResetEvent在多线程编码中最为常用,本文将介绍如何通过AutoResetEvent的线程等待特性实现Silverlig

wcf+silverlight 在ie10兼容模式下正常调用wcf服务,在标准模式下无法调用

问题描述 wcf+silverlight 在ie10兼容模式下正常调用wcf服务,在标准模式下无法调用 wcf+silverlight程序,在chrome,firfox,ie6-ie9下都能正常访问wcf服务,但是在ie10和ie11下访问wcf服务就报500错误了(我用fiddler监听看到的状态).还有在开发环境和部署在本地iis上是能正常访问的.部署到服务器后在ie10和ie11兼容模式下也可以正常访问. 我想问为什么部署到服务器后在ie10和ie11标准模式下无法调用wcf服务? 网站:

silverlight调用wcf服务

问题描述 在silverlight中调用wcf服务得到异步操作的结果为什么e.Rusult的值会ArrayOfElement,我在wcf中返回的是一个list<T>类型的,ArrayOfElement是什么类型啊,它总是提示无法将类型ArrayOfElement饮食转换为System.collection.IEnumerable,求解啊

jQuery Ajax调用WCF服务详细教程_jquery

这两天在写基于WCF服务的后台框架,过程中遇到了一些挫折,经过努力全部解决了,在此分享给大家,使用的工具是Visual Studio 2013. 该后台需要支持通过json来传递和接收数据. 首先,说说搭建过程. 第一步:创建WCF服务应用程序项目WCF. 第二步,创建服务使用的数据类 using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Sch

COM(VB/VBA/Script)利用服务标记调用WCF服务之四:使用配置文件

这几天友人同学说他在COM利用服务标记调用WCF服务的时候遇到一个问题,就是他返回的的Soap消息 大于65536这个wsHttpBinding的缺省值,引发调用错误.需要将MaxReceivedMessageSize更改成可以容纳 大消息内容的值.在我前面的三篇文章中使用的都是缺省的wsHttpBinding,所以不存在这个问题.现在 需要更改缺省值自然就需要增加配置来达到目的.目前最关键的问题就是:是否能让VB/VBA/Script来使 用配置文件呢?如果可以,那如何让VB,VBA, Scr

COM(VB/VBA/Script)利用服务标记调用WCF服务之三使用WSDL契约

前面我们介绍了使用MEX契约的服务标记在COM中调用WCF服务,这种方式是通过MEX终结点动态取得元 数据,使用起来是比较方便:但是有时服务的元数据中可能包含恶意用户可以利用的关于应用程序的敏感 信息,也就是说为了安全考虑有些服务可能不会通过MEX公布元数据信息.如果哦某些服务没有公布元数 据信息,用类型化有比较麻烦,针对这种情况我们该如何在COM中调用WCF服务呢?这时我们可以使用WSDL 契约来进行WCF服务的调用,使用这种方式和使用MEX类似,同样不需要进行类型的注册,信息都是通过动 态得

COM(VB/VBA/Script)利用服务标记调用WCF服务之二使用MEX契约

第一步:创建WCF服务 上一篇我们使用类型化契约的服务标记在COM中调用WCF服务,不过这个有一 定的局限性,因为需要注册类型,所以需要.Net FrameWork,但是在很多情况下COM客户端所在的环境没有 .Net Framework,比如说在Excel中,需要调用一个WCF服务来计算某个单元格的值,而且这个Excel文件可 能分发到许多机器上,你总不能给每台机器都装一个.Net Framework,同时都去给它注册所需的类型吧. 针对这种场景,我们可以使用MEX契约的服务标记来动态得到服务