我有一个客户端应用程序,一旦进入通知服务进度.对服务的方法调用标记为IsOneWay = true,因为通知不需要任何返回值,我不想延迟.
客户端可以向服务通知错误,然后终止.
问题是:单向方法调用在发送消息后是否返回到调用者代码?或者它将消息排队,稍后由另一个线程发送?
这两个进程(客户端和服务)在同一台机器上,我注意到有时(当机器超载时)服务没有收到错误通知.我怀疑我提到的第二个选项发生了,但我不确定.
如果我是对的,我如何确保通知发送并保持方法?
好问题.在客户端应用程序调用方法之前,它会打开通道.该通道用于所有数据通信.有两种发送方式:1)可靠会话 - 当您的数据包被可靠地删除并且重新发送破解的数据包时,2)排序 - 当服务上的请求按照从客户端传输的顺序计算时(不是它们如何传送) .如果您有可靠的有序会话,并且服务主机在关闭应用程序后遇到数据问题,主机将尝试询问客户端重新发送的数据,并且在没有响应后拒绝您请求的所有内容.在其他情况下(不可靠)打开通道后你可以发送数据并销毁通信,单向方法会计算你的请求,如果没有异常.
为了测试一些服务问题的可能性(不完全是你的客户端paroblem,但是有用)我创建了一个解决方案:
1)具有一个文件"IService1.cs"的库项目"WcfContracts":
[ServiceContract]
public interface IService1
{
[OperationContract]
void ThrowException();
[OperationContract(IsOneWay=true)]
void ThrowExceptionUseIsOneWay();
}
Run Code Online (Sandbox Code Playgroud)
2)控制台项目"WcfConsoleHoster",它引用了两个"WcfContracts",并由三个文件组成:
a)Service1.cs,这是服务实现
public class Service1 : WcfContracts.IService1
{
public void ThrowException()
{
throw new Exception("Basic exception");
}
public void ThrowExceptionUseIsOneWay()
{
throw new Exception("Basic exception using IsOneWay=true");
}
}
Run Code Online (Sandbox Code Playgroud)
b)Program.cs,它具有默认入口点并且只是启动服务
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(Service1));
host.Open();
Console.WriteLine("host 1 opened");
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
c)服务"App.config"
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service behaviorConfiguration="behavourHttpGet" name="WcfConsoleHoster.Service1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/WcfConsoleHoster/Service1/" />
</baseAddresses>
</host>
<endpoint binding="wsHttpBinding" contract="WcfContracts.IService1" />
<endpoint address ="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="behavourHttpGet">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Run Code Online (Sandbox Code Playgroud)
3)控制台项目"WcfConsoleClient",它只是调用服务
a)在"Program.cs"中
Console.WriteLine("Wcf client. Press any key to start");
Console.ReadKey();
ChannelFactory<IService1> factory = new ChannelFactory<IService1>("Service1_Endpoint");
IService1 channel = factory.CreateChannel();
//Call service method
channel.ThrowException();
Console.WriteLine("Operation executed");
Console.ReadKey();
Run Code Online (Sandbox Code Playgroud)
b)客户端"App.config"
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint name="Service1_Endpoint"
address="http://localhost:8732/Design_Time_Addresses/WcfConsoleHoster/Service1/"
binding="wsHttpBinding"
contract="WcfContracts.IService1">
</endpoint>
</client>
</system.serviceModel>
</configuration>
Run Code Online (Sandbox Code Playgroud)
1.投掷例外.首先,我们调用双向方法,在服务器主机中抛出异常.然后,此异常返回到客户端,并且通道在客户端引发它,应用程序被销毁.当然你可以使用try()catch {}块来处理这个问题.
让我们通过调用单向方法看起来一样channel.ThrowExceptionUseIsOneWay();.在服务主机中引发异常,但客户端没有异常,我们得到"操作已执行".重要的是要意识到该频道将不可用于下次使用.
因此IsOneWay=true按预期工作 - 它只以一种方式发送消息.您不能从方法返回任何对象(预期为void),并且您不能使用FaultContract,或者在服务启动后获取InvalidOperationException.
2. Thread.Sleep().接下来的测试是关于大规模的操作Thread.Sleep().
IService1延伸到
[OperationContract]
int ThreadSleep();
[OperationContract(IsOneWay=true)]
Run Code Online (Sandbox Code Playgroud)
并且Service1.cs中的实现正在等待5秒钟
public int ThreadSleep()
{
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
return 1;
}
public void ThreadSleepUseIsOneWay()
{
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
}
Run Code Online (Sandbox Code Playgroud)
现在对客户端进行一点修改以计算已用完的呼叫时间
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
//call methode
channel.ThreadSleep();
stopwatch.Stop();
Console.WriteLine(string.Format("Operation executed in {0} seconds", stopwatch.Elapsed.Seconds));
Console.ReadKey();
Run Code Online (Sandbox Code Playgroud)
调用双向方法 ThreadSleep()的结果是"在7秒内执行操作"(线程休眠为5秒,通道初始化为2秒).
One way method与调用channel.ThreadSleepUseIsOneWay()结果"0秒"!没有等待服务响应!
最好使用NetNamedPipeBinding,它在同一台机器上可靠,快速地连接.
| 归档时间: |
|
| 查看次数: |
13560 次 |
| 最近记录: |