Silverlight同步(Synchro“.NET研究”nous)调用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{
????privateint?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>
????上海閔行企業網站設計與制作tyle="color: #0000ff;">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?AsyncCallStatus<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.DataServiceClient?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"?Width="300"?Margin="20">
????????<Grid.RowDefinitions>
????????????<RowDefinition?Height="30"上海網站建設pan>></RowDefinition>
????????????<RowDefinition?Height="30"></RowDefinition>
????????????<RowDefinition?Height="30"></RowDefinition>
????????????<RowDefinition?Height="30"></RowDefinition>
????????????<R上海企業網站制作owDefinition?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"?Grid.Row="3"/>
????????<TextBox?Text="上海徐匯企業網站制作le="color: #808000;">{Binding?Price}"?Grid.Column="1"?Grid.Row="3"></TextBox>?
????????????
????????<Button?Content="查詢"?Grid.Column="1"?Grid.Row="4"?Width="60"?Height="23"?Click="Button_Click"></Button>
????</Grid>
</Grid>
? 通過按鈕執行調用WCF服務接口查詢圖書信息,按鈕事件直接使用上面所寫的圖書門面類(BookFacade)的調用服務方法即可。
private?void?Button_Click(object?sender,?RoutedEventArgs?e){
????try
????{
????????ThreadPool.QueueUserWorkItem(delegate(object?o)
????????{
????????????BookViewModel?viewModel?=?new?BookViewModel();
????????????new?BookFacade().GetBook(viewModel);
????????????Deployment.Current.Dispatcher.BeginInvoke(()?=>?this.DataContext?=?viewModel);
????????});
????}
????catch?(Exception?ex)
????{
????????MessageBox.Show(ex.ToString());
????}
}
? 最終的運行如下圖所示效果:
轉載于:https://www.cnblogs.com/waw/archive/2011/10/18/2216979.html
總結
以上是生活随笔為你收集整理的Silverlight同步(Synchro“.NET研究”nous)调用WCF服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转载】WINCE物理和虚拟地址的问题
- 下一篇: SharePoint 2010 BI(2