silverlight   发布时间:2022-05-04  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Silverlight同步(Synchronous)调用WCF服务大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

  Silverlight的RIA应用中访问远端的Webservice或WCF服务,都是通过异步线程模式调用的。在某些情况下我们的调用是需要同步进行,然Silverlight没有内置同步线程模式调用远端服务接口,但是我们可以通过多线程的处理来伪装出同步调用的实现。在.NET Framework的多线程编程中提供了丰富的线程接口,其中autoResetEvent和ManualResetEvent在

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

 

一、定义WCF服务

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

@H_772_37@[serviceContract]
public @H_772_37@  interface @H_772_37@ IDataservice
{
    [OperationContract]
    Book GetBook();
}

public @H_772_37@  class @H_772_37@ Book
{
     public @H_772_37@  int @H_772_37@ ID {  get @H_772_37@;  set @H_772_37@; }
     public @H_772_37@  String @H_772_37@ NAME {  get @H_772_37@;  set @H_772_37@; }
     public @H_772_37@  String @H_772_37@ Author {  get @H_772_37@;  set @H_772_37@; }
     public @H_772_37@  double @H_772_37@ Price {  get @H_772_37@;  set @H_772_37@; }
}

 

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

public @H_772_37@  class @H_772_37@ Dataservice : IDataservice
{
     public @H_772_37@ Book GetBook()
    {
         return @H_772_37@  new @H_772_37@ Book
        {
            ID  @H_772_37@= @H_772_37@  @H_502_163@1001 @H_772_37@,
            NAME  @H_772_37@= @H_772_37@  " 《三国演义》 " @H_772_37@,
            Author  @H_772_37@= @H_772_37@  " 罗贯中 " @H_772_37@,
            Price  @H_772_37@= @H_772_37@  @H_502_163@89.50 @H_772_37@
        };
    }
}

 

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

 

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

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

public @H_772_37@  class @H_772_37@ viewmodelBase : INotifyPropertyChanged
{
     public @H_772_37@  event @H_772_37@ PropertyChangedEventHandler PropertyChanged;

     protected @H_772_37@  void @H_772_37@ raisePropertyChangedEvent( String @H_772_37@ propertyName)
    {
        var handler  @H_772_37@= @H_772_37@ PropertyChanged;
         if @H_772_37@ (handler  @H_772_37@!= @H_772_37@  null @H_772_37@)
            handler( this @H_772_37@,  new @H_772_37@ PropertyChangedEventArgs(propertyName));
    }
}

 

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

public @H_772_37@  class @H_772_37@ Bookviewmodel : viewmodelBase
{
     private @H_772_37@  int @H_772_37@ iD;
     ///   <sumMary>
    
///  图书ID
    
///   </sumMary>
@H_772_37@     public @H_772_37@  int @H_772_37@ ID
    {
         get @H_772_37@ {  return @H_772_37@ iD; }
         set @H_772_37@
        {
            iD  @H_772_37@= @H_772_37@ value;
            raisePropertyChangedEvent( " ID " @H_772_37@);
        }
    }

     private @H_772_37@  String @H_772_37@ NAME;
     ///   <sumMary>
    
///  图书名称
    
///   </sumMary>
@H_772_37@     public @H_772_37@  String @H_772_37@ NAME
    {
         get @H_772_37@ {  return @H_772_37@ NAME; }
         set @H_772_37@
        {
            NAME  @H_772_37@= @H_772_37@ value;
            raisePropertyChangedEvent( " Name " @H_772_37@);
        }
    }

     private @H_772_37@  String @H_772_37@ author;
     ///   <sumMary>
    
///  图书作者
    
///   </sumMary>
@H_772_37@     public @H_772_37@  String @H_772_37@ Author
    {
         get @H_772_37@ {  return @H_772_37@ author; }
         set @H_772_37@
        {
            author  @H_772_37@= @H_772_37@ value;
            raisePropertyChangedEvent( " Author " @H_772_37@);
        }
    }

     private @H_772_37@  double @H_772_37@ price;
     ///   <sumMary>
    
///  图书价格
    
///   </sumMary>
@H_772_37@     public @H_772_37@  double @H_772_37@ Price
    {
         get @H_772_37@ {  return @H_772_37@ price; }
         set @H_772_37@
        {
            price  @H_772_37@= @H_772_37@ value;
            raisePropertyChangedEvent( " Price " @H_772_37@);
        }
    }
}

 

三、基于AutoResetEvent的同步实现

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

public @H_772_37@  class @H_772_37@ AsyncCallStatus @H_772_37@< @H_772_37@T @H_772_37@> @H_772_37@
{
     public @H_772_37@ AsyncCallStatus()
    {

    }

     public @H_772_37@ T CompletedEventArgs {  get @H_772_37@;  set @H_772_37@; }
}

 

 

public @H_772_37@  class @H_772_37@ BookFacade
{
     private @H_772_37@ AutoResetEvent autoResetEvent  @H_772_37@= @H_772_37@  new @H_772_37@ AutoResetEvent( false @H_772_37@);

     public @H_772_37@  void @H_772_37@ GetBook(Bookviewmodeviewmodel)
    {
         if @H_772_37@ (viewmodel  @H_772_37@== @H_772_37@  null @H_772_37@)
        {
             throw @H_772_37@  new @H_772_37@ argumentNullException( " viewmodel " @H_772_37@,  " 参数不能为空。 " @H_772_37@);
        }

        Dataservice.DataserviceClient client  @H_772_37@= @H_772_37@  new @H_772_37@ Dataservice.DataserviceClient();
        client.GetBookCompleted  @H_772_37@+= @H_772_37@ client_GetBookCompleted;

        var status  @H_772_37@= @H_772_37@  new @H_772_37@ AsyncCallStatus @H_772_37@< @H_772_37@GetBookCompletedEventArgs @H_772_37@> @H_772_37@();
        client.GetBookAsync(status);
         // 阻塞线程
@H_772_37@        autoResetEvent.WaitOne();

         if @H_772_37@ (status.CompletedEventArgs.Error  @H_772_37@!= @H_772_37@  null @H_772_37@)
        {
             throw @H_772_37@ status.CompletedEventArgs.Error;
        }
        var book  @H_772_37@= @H_772_37@ status.CompletedEventArgs.Result;
        viewmodel.ID  @H_772_37@= @H_772_37@ book.ID;
        viewmodel.Name  @H_772_37@= @H_772_37@ book.Name;
        viewmodel.Author  @H_772_37@= @H_772_37@ book.Author;
        viewmodel.Price  @H_772_37@= @H_772_37@ book.Price;
    }

     private @H_772_37@  void @H_772_37@ client_GetBookCompleted( object @H_772_37@ sender, GetBookCompletedEventArgs E)
    {
        var status  @H_772_37@= @H_772_37@ e.UserState  as @H_772_37@ AsyncCallStatus @H_772_37@< @H_772_37@GetBookCompletedEventArgs @H_772_37@> @H_772_37@;

        status.CompletedEventArgs  @H_772_37@= @H_772_37@ e;
         // 终止线程阻塞
@H_772_37@        autoResetEvent.Set();
    }
}

 

 

四、Silverlight前端调用

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

< Grid  x:Name ="LayoutRoot"  BACkground ="White" > @H_772_37@
     < Grid  HorizontalAlignment ="Left"  NAME ="grid1"  VerticalAlignment ="Top"  Width ="300"  Margin ="20" > @H_772_37@
         < Grid.RowDeFinitions > @H_772_37@
             < RowDeFinitio Height ="30" ></ RowDeFinition > @H_772_37@
             < RowDeFinitio Height ="30" ></ RowDeFinition > @H_772_37@
             < RowDeFinitio Height ="30" ></ RowDeFinition > @H_772_37@
             < RowDeFinitio Height ="30" ></ RowDeFinition > @H_772_37@
             < RowDeFinitio Height ="30" ></ RowDeFinition > @H_772_37@
         </ Grid.RowDeFinitions > @H_772_37@
         < Grid.columnDeFinitions > @H_772_37@
             < columnDeFinitio Width ="60" ></ columnDeFinition > @H_772_37@
             < columnDeFinitio Width ="*" ></ columnDeFinition > @H_772_37@
         </ Grid.columnDeFinitions > @H_772_37@
         < sdk:Label   HorizontalAlignment ="Left"  Content ="图书编号:"  VerticalAlignment ="Center"  Grid.column ="0"  Grid.Row ="0" /> @H_772_37@
         < TextBox  Text =" {Binding ID} "  Grid.column ="1"  Grid.Row ="0" ></ TextBox > @H_772_37@
         < sdk:Label   HorizontalAlignment ="Left"  Content ="图书名称:"  VerticalAlignment ="Center"  Grid.column ="0"  Grid.Row ="1" /> @H_772_37@
         < TextBox  Text =" {Binding NAME} "  Grid.column ="1"  Grid.Row ="1" ></ TextBox > @H_772_37@
         < sdk:Label   HorizontalAlignment ="Left"  Content ="图书作者:"  VerticalAlignment ="Center"  Grid.column ="0"  Grid.Row ="2" /> @H_772_37@
         < TextBox  Text =" {Binding Author} "  Grid.column ="1"  Grid.Row ="2" ></ TextBox > @H_772_37@
         < sdk:Label   HorizontalAlignment ="Left"  Content ="图书价格:"  VerticalAlignment ="Center"  Grid.column ="0"  Grid.Row ="3" /> @H_772_37@
         < TextBox  Text =" {Binding PricE} "  Grid.column ="1"  Grid.Row ="3" ></ TextBox > @H_772_37@ 
            
         < Button  Content ="查询"  Grid.column ="1"  Grid.Row ="4"  Width ="60"  Height ="23"  Click ="Button_Click" ></ Button > @H_772_37@
     </ Grid > @H_772_37@
</ Grid >

 

   通过按钮执行调用WCF服务接口查询图书信息,按钮事件直接使用上面所写的图书门面类(BookFacade)的调用服务方法即可。

private @H_772_37@  void @H_772_37@ Button_Click( object @H_772_37@ sender, routedEventArgs E)
{
     try @H_772_37@
    {
        ThreadPool.QueueUserWorkItem( delegate @H_772_37@( object @H_772_37@ o)
        {
            Bookviewmodeviewmodel  @H_772_37@= @H_772_37@  new @H_772_37@ Bookviewmodel();

             new @H_772_37@ BookFacade().GetBook(viewmodel);

            Deployment.Current.Dispatcher.beginInvoke(()  @H_772_37@=> @H_772_37@  this @H_772_37@.DataContext  @H_772_37@= @H_772_37@ viewmodel);
        });
    }
     catch @H_772_37@ (Exception eX)
    {
        messageBox.Show(ex.ToString());
    }
}

 

   最终的运行如下图所示效果

  

Silverlight同步(Synchronous)调用WCF服务

 

  

Silverlight同步(Synchronous)调用WCF服务

大佬总结

以上是大佬教程为你收集整理的Silverlight同步(Synchronous)调用WCF服务全部内容,希望文章能够帮你解决Silverlight同步(Synchronous)调用WCF服务所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。