稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)
2011-11-28 15:35
471 查看
[索引页]
[源码下载]
稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)
作者:webabcd
介绍
Silverlight
2.0 调用 WCF 的双向通信服务(Duplex Service) 。开发一个服务端主动向客服端发送股票信息的程序,首先客户端先向服务端发送需要监控的股票的股票代码,然后服务端在该股信息发生变化的时候将信息推送到客户端。
服务端:
定义服务契约及回调接口
从当前上下文获取回调的客户端信道
需要的话则向客户端信道“推”消息
客户端:
构造
PollingDuplexHttpBinding 并在其上创建 IDuplexSessionChannel 的信道工厂
异步方式打开信道工厂
异步方式打开信道
构造需要发送到服务端的消息
System.ServiceModel.Channels.Message
异步向服务端发送消息
监听指定信道,用于异步方式接收服务端返回的消息
不需要再接收服务端的消息则关闭信道
在线DEMO
/article/4589581.html
示例
服务端:
IDuplexService.cs
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections.Generic;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Linq;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Runtime.Serialization;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Text;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Channels;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// IDuplexService - 双工(Duplex)服务契约
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// CallbackContract - 双工(Duplex)服务的回调类型
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
[ServiceContract(Namespace = "Silverlight20", CallbackContract = typeof(IDuplexClient))]
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public interface IDuplexService
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 客户端向服务端发送消息的方法
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
/// <param name="receivedMessage">客户端向服务端发送的消息 System.ServiceModel.Channels.Message</param>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[OperationContract(IsOneWay = true)]
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void SendStockCode(Message receivedMessage);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 双工(Duplex)服务的回调接口
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public interface IDuplexClient
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 客户端接收服务端发送过来的消息的方法
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
/// <param name="returnMessage">服务端向客户端发送的消息 System.ServiceModel.Channels.Message</param>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[OperationContract(IsOneWay = true)]
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void ReceiveStockMessage(Message returnMessage);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
DuplexService.cs
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections.Generic;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Linq;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Runtime.Serialization;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Text;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Channels;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Threading;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Activation;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.IO;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// Duplex 服务的服务端的实现
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 本文以客户端向服务端提交股票代码,服务端定时向客户端发送股票信息为例
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public class DuplexService : IDuplexService
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexClient _client;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
bool _status = true;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 客户端向服务端发送股票代码的方法
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
/// <param name="receivedMessage">包含股票代码的 System.ServiceModel.Channels.Message </param>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void SendStockCode(Message receivedMessage)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 获取当前上下文的回调信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 如果发生错误则不再执行
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
OperationContext.Current.Channel.Faulted += new EventHandler(delegate { _status = false; });
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 获取用户提交的股票代码
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string stockCode = receivedMessage.GetBody<string>();
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 每3秒向客户端发送一次股票信息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
while (_status)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 构造需要发送到客户端的 System.ServiceModel.Channels.Message
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Duplex 服务仅支持 Soap11 , Action 为请求的目的地(需要执行的某行为的路径)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Message stockMessage = Message.CreateMessage(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
MessageVersion.Soap11,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"Silverlight20/IDuplexService/ReceiveStockMessage",
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string.Format("StockCode: {0}; StockPrice: {1}; CurrentTime: {2}",
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
stockCode,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new Random().Next(1, 200),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DateTime.Now.ToString()));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
try
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 向客户端“推”数据
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_client.ReceiveStockMessage(stockMessage);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
catch (Exception ex)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 出错则记日志
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
using (StreamWriter sw = new StreamWriter(@"C:\Silverlight_Duplex_Log.txt", true))
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sw.Write(ex.ToString());
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sw.WriteLine();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
System.Threading.Thread.Sleep(3000);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
PollingDuplexServiceHostFactory.cs
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections.Generic;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Linq;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Channels;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Activation;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/* 以下部分摘自文档 */
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
// 服务 svc 文件的 Factory 要指定为此类
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public class PollingDuplexServiceHostFactory : ServiceHostFactoryBase
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public override ServiceHostBase CreateServiceHost(string constructorString,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Uri[] baseAddresses)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return new PollingDuplexSimplexServiceHost(baseAddresses);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
class PollingDuplexSimplexServiceHost : ServiceHost
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public PollingDuplexSimplexServiceHost(params System.Uri[] addresses)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
base.InitializeDescription(typeof(DuplexService), new UriSchemeKeyedCollection(addresses));
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected override void InitializeRuntime()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 配置 WCF 服务与 Silverlight 客户端之间的 Duplex 通信
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Silverlight 客户端定期轮询网络层上的服务,并检查回调信道上由服务端发送的所有新的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 该服务会将回调信道上的由服务端发送的所有消息进行排队,并在客户端轮询服务时将这些消息传递到该客户端
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
PollingDuplexBindingElement pdbe = new PollingDuplexBindingElement()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// ServerPollTimeout - 轮询超时时间
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// InactivityTimeout - 服务端与客户端在此超时时间内无任何消息交换的情况下,服务会关闭其会话
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ServerPollTimeout = TimeSpan.FromSeconds(3),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
InactivityTimeout = TimeSpan.FromMinutes(1)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
};
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 为服务契约(service contract)添加一个终结点(endpoint)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Duplex 服务仅支持 Soap11
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.AddServiceEndpoint(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
typeof(IDuplexService),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new CustomBinding(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
pdbe,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new TextMessageEncodingBindingElement(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
MessageVersion.Soap11,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
System.Text.Encoding.UTF8),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new HttpTransportBindingElement()),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"");
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
base.InitializeRuntime();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
DuplexService.svc
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
<%@ ServiceHost Language="C#" Debug="true" Service="DuplexService" CodeBehind="~/App_Code/DuplexService.cs" Factory="PollingDuplexServiceHostFactory" %>
客户端:
DuplexService.xaml
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<UserControl x:Class="Silverlight20.Communication.DuplexService"
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<StackPanel HorizontalAlignment="Left" Margin="5">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<TextBox x:Name="txtStockCode" Text="请输入股票代码" Margin="5" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<Button x:Name="btnSubmit" Content="获取股票信息" Click="btnSubmit_Click" Margin="5" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<Button x:Name="btnStop" Content="停止获取" Click="btnStop_Click" Margin="5" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<TextBlock x:Name="lblStockMessage" Margin="5" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</StackPanel>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</UserControl>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
DuplexService.xaml.cs
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections.Generic;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Linq;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Net;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Controls;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Documents;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Input;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Media;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Media.Animation;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Shapes;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Channels;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Threading;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.IO;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace Silverlight20.Communication
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public partial class DuplexService : UserControl
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
SynchronizationContext _syncContext;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 是否接收服务端发送过来的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
bool _status = true;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public DuplexService()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
InitializeComponent();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void btnSubmit_Click(object sender, RoutedEventArgs e)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_status = true;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// UI 线程
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_syncContext = SynchronizationContext.Current;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
PollingDuplexHttpBinding binding = new PollingDuplexHttpBinding()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// InactivityTimeout - 服务端与客户端在此超时时间内无任何消息交换的情况下,服务会关闭其会话
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
InactivityTimeout = TimeSpan.FromMinutes(1)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
};
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 构造 IDuplexSessionChannel 的信道工厂
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IChannelFactory<IDuplexSessionChannel> factory =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
binding.BuildChannelFactory<IDuplexSessionChannel>(new BindingParameterCollection());
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 打开信道工厂
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult factoryOpenResult =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
factory.BeginOpen(new AsyncCallback(OnOpenCompleteFactory), factory);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (factoryOpenResult.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 如果信道工厂被打开的这个 异步操作 已经被 同步完成 则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOpenFactory(factoryOpenResult);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void btnStop_Click(object sender, RoutedEventArgs e)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_status = false;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnOpenCompleteFactory(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOpenFactory(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteOpenFactory(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IChannelFactory<IDuplexSessionChannel> factory = result.AsyncState as IChannelFactory<IDuplexSessionChannel>;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以打开信道工厂
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
factory.EndOpen(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 在信道工厂上根据指定的地址创建信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
factory.CreateChannel(new EndpointAddress("http://localhost:3036/DuplexService.svc"));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 打开信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult channelOpenResult =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.BeginOpen(new AsyncCallback(OnOpenCompleteChannel), channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (channelOpenResult.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 如果信道被打开的这个 异步操作 已经被 同步完成 则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOpenChannel(channelOpenResult);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnOpenCompleteChannel(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOpenChannel(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteOpenChannel(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel = result.AsyncState as IDuplexSessionChannel;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以打开信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.EndOpen(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 构造需要发送到服务端的 System.ServiceModel.Channels.Message (客户端终结点与服务端终结点之间的通信单元)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Message message = Message.CreateMessage(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.GetProperty<MessageVersion>(), // MessageVersion.Soap11 (Duplex 服务仅支持 Soap11)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"Silverlight20/IDuplexService/SendStockCode", // Action 为请求的目的地(需要执行的某行为的路径)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
txtStockCode.Text);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 向目的地发送消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult resultChannel =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.BeginSend(message, new AsyncCallback(OnSend), channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (resultChannel.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 如果向目的地发送消息的这个 异步操作 已经被 同步完成 则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOnSend(resultChannel);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 监听指定的信道,用于接收返回的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ReceiveLoop(channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnSend(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOnSend(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteOnSend(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
try
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel = (IDuplexSessionChannel)result.AsyncState;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以完成向目的地发送消息的操作
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.EndSend(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
catch (Exception ex)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_syncContext.Post(WriteText, ex.ToString() + Environment.NewLine);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void ReceiveLoop(IDuplexSessionChannel channel)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 监听指定的信道,用于接收返回的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult result =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.BeginReceive(new AsyncCallback(OnReceiveComplete), channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteReceive(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnReceiveComplete(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteReceive(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteReceive(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel = (IDuplexSessionChannel)result.AsyncState;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
try
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以接收到服务端发过来的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Message receivedMessage = channel.EndReceive(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (receivedMessage == null)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 服务端会话已被关闭
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 此时应该关闭客户端会话,或向服务端发送消息以启动一个新的会话
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 将接收到的信息输出到界面上
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string text = receivedMessage.GetBody<string>();
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_syncContext.Post(WriteText, text + Environment.NewLine);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (!_status)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 关闭信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult resultFactory =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.BeginClose(new AsyncCallback(OnCloseChannel), channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (resultFactory.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteCloseChannel(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 继续监听指定的信道,用于接收返回的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ReceiveLoop(channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
catch (Exception ex)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 出错则记日志
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
using (StreamWriter sw = new StreamWriter(@"C:\Silverlight_Duplex_Log.txt", true))
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sw.Write(ex.ToString());
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sw.WriteLine();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnCloseChannel(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteCloseChannel(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteCloseChannel(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel = (IDuplexSessionChannel)result.AsyncState;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以关闭信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.EndClose(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void WriteText(object text)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 将信息打到界面上
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
lblStockMessage.Text += (string)text;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
OK
[源码下载]
[源码下载]
稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)
作者:webabcd
介绍
Silverlight
2.0 调用 WCF 的双向通信服务(Duplex Service) 。开发一个服务端主动向客服端发送股票信息的程序,首先客户端先向服务端发送需要监控的股票的股票代码,然后服务端在该股信息发生变化的时候将信息推送到客户端。
服务端:
定义服务契约及回调接口
从当前上下文获取回调的客户端信道
需要的话则向客户端信道“推”消息
客户端:
构造
PollingDuplexHttpBinding 并在其上创建 IDuplexSessionChannel 的信道工厂
异步方式打开信道工厂
异步方式打开信道
构造需要发送到服务端的消息
System.ServiceModel.Channels.Message
异步向服务端发送消息
监听指定信道,用于异步方式接收服务端返回的消息
不需要再接收服务端的消息则关闭信道
在线DEMO
/article/4589581.html
示例
服务端:
IDuplexService.cs
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections.Generic;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Linq;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Runtime.Serialization;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Text;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Channels;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// IDuplexService - 双工(Duplex)服务契约
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// CallbackContract - 双工(Duplex)服务的回调类型
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
[ServiceContract(Namespace = "Silverlight20", CallbackContract = typeof(IDuplexClient))]
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public interface IDuplexService
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 客户端向服务端发送消息的方法
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
/// <param name="receivedMessage">客户端向服务端发送的消息 System.ServiceModel.Channels.Message</param>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[OperationContract(IsOneWay = true)]
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void SendStockCode(Message receivedMessage);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 双工(Duplex)服务的回调接口
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public interface IDuplexClient
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 客户端接收服务端发送过来的消息的方法
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
/// <param name="returnMessage">服务端向客户端发送的消息 System.ServiceModel.Channels.Message</param>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
[OperationContract(IsOneWay = true)]
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void ReceiveStockMessage(Message returnMessage);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
DuplexService.cs
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections.Generic;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Linq;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Runtime.Serialization;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Text;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Channels;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Threading;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Activation;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.IO;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// Duplex 服务的服务端的实现
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 本文以客户端向服务端提交股票代码,服务端定时向客户端发送股票信息为例
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public class DuplexService : IDuplexService
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexClient _client;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
bool _status = true;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/// <summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// 客户端向服务端发送股票代码的方法
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
/// <param name="receivedMessage">包含股票代码的 System.ServiceModel.Channels.Message </param>
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public void SendStockCode(Message receivedMessage)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 获取当前上下文的回调信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_client = OperationContext.Current.GetCallbackChannel<IDuplexClient>();
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 如果发生错误则不再执行
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
OperationContext.Current.Channel.Faulted += new EventHandler(delegate { _status = false; });
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 获取用户提交的股票代码
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string stockCode = receivedMessage.GetBody<string>();
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 每3秒向客户端发送一次股票信息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
while (_status)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 构造需要发送到客户端的 System.ServiceModel.Channels.Message
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Duplex 服务仅支持 Soap11 , Action 为请求的目的地(需要执行的某行为的路径)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Message stockMessage = Message.CreateMessage(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
MessageVersion.Soap11,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"Silverlight20/IDuplexService/ReceiveStockMessage",
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string.Format("StockCode: {0}; StockPrice: {1}; CurrentTime: {2}",
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
stockCode,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new Random().Next(1, 200),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
DateTime.Now.ToString()));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
try
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 向客户端“推”数据
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_client.ReceiveStockMessage(stockMessage);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
catch (Exception ex)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 出错则记日志
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
using (StreamWriter sw = new StreamWriter(@"C:\Silverlight_Duplex_Log.txt", true))
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sw.Write(ex.ToString());
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sw.WriteLine();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
System.Threading.Thread.Sleep(3000);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
PollingDuplexServiceHostFactory.cs
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections.Generic;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Linq;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Web;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Channels;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Activation;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/* 以下部分摘自文档 */
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
// 服务 svc 文件的 Factory 要指定为此类
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
public class PollingDuplexServiceHostFactory : ServiceHostFactoryBase
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public override ServiceHostBase CreateServiceHost(string constructorString,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Uri[] baseAddresses)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return new PollingDuplexSimplexServiceHost(baseAddresses);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
class PollingDuplexSimplexServiceHost : ServiceHost
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public PollingDuplexSimplexServiceHost(params System.Uri[] addresses)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
base.InitializeDescription(typeof(DuplexService), new UriSchemeKeyedCollection(addresses));
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
protected override void InitializeRuntime()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 配置 WCF 服务与 Silverlight 客户端之间的 Duplex 通信
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Silverlight 客户端定期轮询网络层上的服务,并检查回调信道上由服务端发送的所有新的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 该服务会将回调信道上的由服务端发送的所有消息进行排队,并在客户端轮询服务时将这些消息传递到该客户端
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
PollingDuplexBindingElement pdbe = new PollingDuplexBindingElement()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// ServerPollTimeout - 轮询超时时间
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// InactivityTimeout - 服务端与客户端在此超时时间内无任何消息交换的情况下,服务会关闭其会话
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ServerPollTimeout = TimeSpan.FromSeconds(3),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
InactivityTimeout = TimeSpan.FromMinutes(1)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
};
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 为服务契约(service contract)添加一个终结点(endpoint)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Duplex 服务仅支持 Soap11
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
this.AddServiceEndpoint(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
typeof(IDuplexService),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new CustomBinding(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
pdbe,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new TextMessageEncodingBindingElement(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
MessageVersion.Soap11,
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
System.Text.Encoding.UTF8),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
new HttpTransportBindingElement()),
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"");
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
base.InitializeRuntime();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
DuplexService.svc
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
<%@ ServiceHost Language="C#" Debug="true" Service="DuplexService" CodeBehind="~/App_Code/DuplexService.cs" Factory="PollingDuplexServiceHostFactory" %>
客户端:
DuplexService.xaml
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<UserControl x:Class="Silverlight20.Communication.DuplexService"
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<StackPanel HorizontalAlignment="Left" Margin="5">
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<TextBox x:Name="txtStockCode" Text="请输入股票代码" Margin="5" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<Button x:Name="btnSubmit" Content="获取股票信息" Click="btnSubmit_Click" Margin="5" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<Button x:Name="btnStop" Content="停止获取" Click="btnStop_Click" Margin="5" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
<TextBlock x:Name="lblStockMessage" Margin="5" />
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</StackPanel>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
</UserControl>
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
DuplexService.xaml.cs
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Collections.Generic;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Linq;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Net;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Controls;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Documents;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Input;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Media;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Media.Animation;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Windows.Shapes;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.ServiceModel.Channels;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.Threading;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System.IO;
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace Silverlight20.Communication
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public partial class DuplexService : UserControl
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
SynchronizationContext _syncContext;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 是否接收服务端发送过来的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
bool _status = true;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public DuplexService()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
InitializeComponent();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void btnSubmit_Click(object sender, RoutedEventArgs e)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_status = true;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// UI 线程
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_syncContext = SynchronizationContext.Current;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
PollingDuplexHttpBinding binding = new PollingDuplexHttpBinding()
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// InactivityTimeout - 服务端与客户端在此超时时间内无任何消息交换的情况下,服务会关闭其会话
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
InactivityTimeout = TimeSpan.FromMinutes(1)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
};
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 构造 IDuplexSessionChannel 的信道工厂
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IChannelFactory<IDuplexSessionChannel> factory =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
binding.BuildChannelFactory<IDuplexSessionChannel>(new BindingParameterCollection());
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 打开信道工厂
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult factoryOpenResult =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
factory.BeginOpen(new AsyncCallback(OnOpenCompleteFactory), factory);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (factoryOpenResult.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 如果信道工厂被打开的这个 异步操作 已经被 同步完成 则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOpenFactory(factoryOpenResult);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private void btnStop_Click(object sender, RoutedEventArgs e)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_status = false;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnOpenCompleteFactory(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOpenFactory(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteOpenFactory(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IChannelFactory<IDuplexSessionChannel> factory = result.AsyncState as IChannelFactory<IDuplexSessionChannel>;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以打开信道工厂
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
factory.EndOpen(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 在信道工厂上根据指定的地址创建信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
factory.CreateChannel(new EndpointAddress("http://localhost:3036/DuplexService.svc"));
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 打开信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult channelOpenResult =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.BeginOpen(new AsyncCallback(OnOpenCompleteChannel), channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (channelOpenResult.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 如果信道被打开的这个 异步操作 已经被 同步完成 则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOpenChannel(channelOpenResult);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnOpenCompleteChannel(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOpenChannel(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteOpenChannel(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel = result.AsyncState as IDuplexSessionChannel;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以打开信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.EndOpen(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 构造需要发送到服务端的 System.ServiceModel.Channels.Message (客户端终结点与服务端终结点之间的通信单元)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Message message = Message.CreateMessage(
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.GetProperty<MessageVersion>(), // MessageVersion.Soap11 (Duplex 服务仅支持 Soap11)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
"Silverlight20/IDuplexService/SendStockCode", // Action 为请求的目的地(需要执行的某行为的路径)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
txtStockCode.Text);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 向目的地发送消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult resultChannel =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.BeginSend(message, new AsyncCallback(OnSend), channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (resultChannel.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 如果向目的地发送消息的这个 异步操作 已经被 同步完成 则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOnSend(resultChannel);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 监听指定的信道,用于接收返回的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ReceiveLoop(channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnSend(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 该异步操作已被同步完成的话则不做任何操作,反之则执行下一步
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteOnSend(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteOnSend(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
try
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel = (IDuplexSessionChannel)result.AsyncState;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以完成向目的地发送消息的操作
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.EndSend(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
catch (Exception ex)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_syncContext.Post(WriteText, ex.ToString() + Environment.NewLine);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void ReceiveLoop(IDuplexSessionChannel channel)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 监听指定的信道,用于接收返回的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult result =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.BeginReceive(new AsyncCallback(OnReceiveComplete), channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteReceive(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnReceiveComplete(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteReceive(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteReceive(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel = (IDuplexSessionChannel)result.AsyncState;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
try
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以接收到服务端发过来的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
Message receivedMessage = channel.EndReceive(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (receivedMessage == null)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 服务端会话已被关闭
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 此时应该关闭客户端会话,或向服务端发送消息以启动一个新的会话
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 将接收到的信息输出到界面上
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
string text = receivedMessage.GetBody<string>();
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
_syncContext.Post(WriteText, text + Environment.NewLine);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (!_status)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 关闭信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IAsyncResult resultFactory =
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.BeginClose(new AsyncCallback(OnCloseChannel), channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (resultFactory.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteCloseChannel(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 继续监听指定的信道,用于接收返回的消息
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ReceiveLoop(channel);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
catch (Exception ex)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 出错则记日志
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
using (StreamWriter sw = new StreamWriter(@"C:\Silverlight_Duplex_Log.txt", true))
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sw.Write(ex.ToString());
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
sw.WriteLine();
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void OnCloseChannel(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (result.CompletedSynchronously)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
return;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CompleteCloseChannel(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void CompleteCloseChannel(IAsyncResult result)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
IDuplexSessionChannel channel = (IDuplexSessionChannel)result.AsyncState;
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 完成异步操作,以关闭信道
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
channel.EndClose(result);
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
void WriteText(object text)
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 将信息打到界面上
![](http://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
lblStockMessage.Text += (string)text;
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
}
OK
[源码下载]
相关文章推荐
- 上接稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)
- 稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)
- 稳扎稳打Silverlight(23) - 2.0通信之调用WCF的双向通信(Duplex Service)
- 稳扎稳打Silverlight(22) - 2.0通信之调用WCF服务, 对传输信息做加密
- 稳扎稳打Silverlight(22) - 2.0通信之调用WCF服务, 对传输信息做加密
- 稳扎稳打Silverlight(22) - 2.0通信之调用WCF服务, 对传输信息做加密
- 稳扎稳打Silverlight(19) - 2.0通信之调用REST服务,处理JSON格式, XML格式, RSS/ATOM格式的数据
- 稳扎稳打Silverlight(19) - 2.0通信之调用REST服务,处理JSON格式, XML格式, RSS/ATOM格式的数据
- 稳扎稳打Silverlight(19) - 2.0通信之调用REST服务,处理JSON格式, XML格式, RSS/ATOM格式的数据
- 稳扎稳打Silverlight(28) - 2.0通信之调用ADO.NET Data Services(数据服务)
- 稳扎稳打Silverlight(28) - 2.0通信之调用ADO.NET Data Services(数据服务)
- 稳扎稳打Silverlight(28) - 2.0通信之调用ADO.NET Data Services(数据服务)
- 稳扎稳打Silverlight(19) - 2.0通信之调用REST服务,处理JSON格式, XML格式, RSS/ATOM格式的数据
- 上接稳扎稳打Silverlight(19) - 2.0通信之调用REST服务,处理JSON格式, XML格式, RSS/ATOM格式的数据
- 稳扎稳打Silverlight(59) - 4.0通信之WCF RIA Services: 数据验证
- Silverlight 结合WCF Duplex Service聊天程序出炉
- 稳扎稳打Silverlight(60) - 4.0通信之WCF RIA Services: 权限验证
- 稳扎稳打Silverlight(61) - 4.0通信之WCF RIA Services: 自定义服务端排序和分页
- Silverlight中服务通信方式的选择(WCF、Data Service、Ria Service)
- 稳扎稳打Silverlight(21) - 2.0通信之WebRequest和WebResponse, 对指定的URI发出请求以及接收响应