当前位置:  开发笔记 > 运维 > 正文

在应用程序终止时,WCF中的IsOneWay = true的方法会发生什么

如何解决《在应用程序终止时,WCF中的IsOneWay=true的方法会发生什么》经验,为你挑选了1个好方法。

我有一个客户端应用程序,一旦进入通知服务进度.对服务的方法调用标记为IsOneWay = true,因为通知不需要任何返回值,我不想延迟.

客户端可以向服务通知错误,然后终止.

问题是:单向方法调用在发送消息后是否返回到调用者代码?或者它将消息排队,稍后由另一个线程发送?

这两个进程(客户端和服务)在同一台机器上,我注意到有时(当机器超载时)服务没有收到错误通知.我怀疑我提到的第二个选项发生了,但我不确定.

如果我是对的,我如何确保通知发送并保持方法?



1> Artru..:

好问题.在客户端应用程序调用方法之前,它会打开通道.该通道用于所有数据通信.有两种发送方式:1)可靠会话 - 当您的数据包被可靠地删除并且重新发送破解的数据包时,2)排序 - 当服务上的请求按照从客户端传输的顺序计算时(不是它们如何传送) .如果您有可靠的有序会话,并且服务主机在关闭应用程序后遇到数据问题,主机将尝试询问客户端重新发送的数据,并且在没有响应后拒绝您请求的所有内容.在其他情况下(不可靠)打开通道后你可以发送数据并销毁通信,单向方法会计算你的请求,如果没有异常.

为了测试一些服务问题的可能性(不完全是你的客户端paroblem,但是有用)我创建了一个解决方案:

1)具有一个文件"IService1.cs"的库项目"WcfContracts":

    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        void ThrowException();

        [OperationContract(IsOneWay=true)]
        void ThrowExceptionUseIsOneWay();
    }

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");
        }
}

b)Program.cs,它具有默认入口点并且只是启动服务

static void Main(string[] args)
    {
        ServiceHost host = new ServiceHost(typeof(Service1));
        host.Open();
        Console.WriteLine("host 1 opened");
        Console.ReadKey();
    }

c)服务"App.config"



  
    
      
        
          
            
          
        
                
        
      
    
    
      
        
          
        
      
    
  

3)控制台项目"WcfConsoleClient",它只是调用服务

a)在"Program.cs"中

Console.WriteLine("Wcf client. Press any key to start");
Console.ReadKey();
ChannelFactory factory = new ChannelFactory("Service1_Endpoint");
IService1 channel = factory.CreateChannel();
//Call service method
channel.ThrowException();

Console.WriteLine("Operation executed");
Console.ReadKey();

b)客户端"App.config"



  
    
      
      
    
  


1.投掷例外.首先,我们调用双向方法,在服务器主机中抛出异常.然后,此异常返回到客户端,并且通道在客户端引发它,应用程序被销毁.当然你可以使用try()catch {}块来处理这个问题.

让我们通过调用单向方法看起来一样channel.ThrowExceptionUseIsOneWay();.在服务主机中引发异常,但客户端没有异常,我们得到"操作已执行".重要的是要意识到该频道将不可用于下次使用.

因此IsOneWay=true按预期工作 - 它只以一种方式发送消息.您不能从方法返回任何对象(预期为void),并且您不能使用FaultContract,或者在服务启动后获取InvalidOperationException.

2. Thread.Sleep().接下来的测试是关于大规模的操作Thread.Sleep(). IService1延伸到

  [OperationContract]
  int ThreadSleep();

  [OperationContract(IsOneWay=true)]

并且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));
}

现在对客户端进行一点修改以计算已用完的呼叫时间

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();

调用双向方法 ThreadSleep()的结果是"在7秒内执行操作"(线程休眠为5秒,通道初始化为2秒).

One way method与调用channel.ThreadSleepUseIsOneWay()结果"0秒"!没有等待服务响应!

最好使用NetNamedPipeBinding,它在同一台机器上可靠,快速地连接.

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有