Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF双工服务通道关闭_C#_Wcf - Fatal编程技术网

C# WCF双工服务通道关闭

C# WCF双工服务通道关闭,c#,wcf,C#,Wcf,我有一个基于WCF双工服务的应用程序。当用户“重新启动”应用程序所做的工作时,我遇到了问题。。。在引擎盖下,客户端关闭与WCF服务的连接并创建另一个连接。服务合同的定义如下 [ServiceContract(Namespace="net.tcp://namespace.MyService", SessionMode=SessionMode.Required, CallbackContract=typeof(IServiceCallback))] public interface

我有一个基于WCF双工服务的应用程序。当用户“重新启动”应用程序所做的工作时,我遇到了问题。。。在引擎盖下,客户端关闭与WCF服务的连接并创建另一个连接。服务合同的定义如下

[ServiceContract(Namespace="net.tcp://namespace.MyService",
    SessionMode=SessionMode.Required,
    CallbackContract=typeof(IServiceCallback))]
public interface IMyService
{
    [OperationContract(IsOneWay=true)]
    void DoWork();
}


public interface IServiceCallback
{
    [OperationContract(IsOneWay=true)]
    void SendMessage(string message);
}
实施定义为:

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single,
    InstanceContextMode = InstanceContextMode.PerSession,
    UseSynchronizationContext = false,
    IncludeExceptionDetailInFaults = true)]
public class MyService : IMyService
{
    public void DoWork()
    {
        var callback = OperationContext.Current.GetCallbackChannel<IServiceCallback>();
        callback.SendMessage("Hello, world.");
    }
}
在建立新连接之前,我正在尝试以下操作:

        try
        {
            if (_context != null)
            {
                _context.ReleaseServiceInstance();
                _context.Close();                    
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
            if (_context != null)
            {
                _context.Abort();
            }
        }
我看到的问题是_context.Close()调用总是超时并抛出异常。虽然我当时正在中止该频道,但我觉得这是不对的,我相信这是我的应用程序冻结的原因。有人知道Close()调用失败的原因吗

编辑:我之前错过了一些可能与回调实现相关的内容。它看起来像这样:

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Single, 
    UseSynchronizationContext = false, 
    IncludeExceptionDetailInFaults = true)]
public class CallbackImplementation : IServiceCallback
{
    public void SendMessage(string message)
    {
        // Do something with the message
    }
}
异常消息为“ServiceHost关闭操作在00:00:30后超时。这可能是因为客户端未能在所需时间内关闭会话通道。分配给此操作的时间可能是较长超时的一部分。”。没有内在的例外


感谢您尝试过receiveTimeout=“infinite”以查看是否仍然收到错误。您可能会发现创建错误的不是超时。您是否考虑过创建一个基本的客户端类,自动保持连接直到物理关闭?

我现在看不出有什么问题,但我经常发现在客户端和服务器上运行跟踪并检查结果通常会让我找到解决方案。将其放入.config文件(客户端和服务器)中,确保路径指向存在的文件夹。运行您的应用程序,获取故障信息,然后关闭所有设备并运行SvcTraceViewer.exe读取结果

<system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Information,ActivityTracing"
        propagateActivity="true">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add initializeData="C:\logs\TracingAndLogging-service.svclog" type="System.Diagnostics.XmlWriterTraceListener"
        name="xml" />
    </sharedListeners>
    <trace autoflush="true" />
</system.diagnostics>

猜测一下,这可能是由于使用了
并发模式.Single而导致的死锁

可能发生的情况是,当服务器仍在处理原始请求(反之亦然)时,它正在尝试回调客户端。所以服务器正试图回叫客户端,但客户端正在阻塞,因为它仍在等待服务器的响应。嘿,普雷斯托,死锁,最后超时


问题不仅在于并发性,还在于绑定类型


确保服务和回调的并发模式是朝着正确方向迈出的一步。但是将绑定从netTcpBinding更改为wsDualHttpBinding最终解决了这个问题

尝试添加一个
OnClose
事件处理程序。查看是否在
回调
服务器端触发事件。谢谢,我刚刚尝试过:关闭和关闭事件都在触发。但服务仍然超时?您是否尝试过在绑定上设置
CloseTimeout
?是的,我已经在两端设置了CloseTimeout,并且出现了相同的问题。您可以发布异常吗?另外,应用程序响应的一个快速解决方案是这样做:
Task.StartNew(()=>{u context.Close();})
        try
        {
            if (_context != null)
            {
                _context.ReleaseServiceInstance();
                _context.Close();                    
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
            if (_context != null)
            {
                _context.Abort();
            }
        }
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Single, 
    UseSynchronizationContext = false, 
    IncludeExceptionDetailInFaults = true)]
public class CallbackImplementation : IServiceCallback
{
    public void SendMessage(string message)
    {
        // Do something with the message
    }
}
<system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="Information,ActivityTracing"
        propagateActivity="true">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
      <source name="System.ServiceModel.MessageLogging">
        <listeners>
          <add name="xml" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add initializeData="C:\logs\TracingAndLogging-service.svclog" type="System.Diagnostics.XmlWriterTraceListener"
        name="xml" />
    </sharedListeners>
    <trace autoflush="true" />
</system.diagnostics>