C# 两个客户端之间的不同服务行为

C# 两个客户端之间的不同服务行为,c#,wcf,C#,Wcf,我有一个WCF服务,我需要将其合并到现有应用程序中。 服务接口: [ServiceContract(CallbackContract = typeof(IClientCallback))] public interface IExecutionService { [OperationContract] ExecutionStatus Execute(string path); [OperationContract]

我有一个
WCF
服务,我需要将其合并到现有应用程序中。
服务接口:

[ServiceContract(CallbackContract = typeof(IClientCallback))]
    public interface IExecutionService
    {
        [OperationContract]
        ExecutionStatus Execute(string path);

        [OperationContract]
        ExecutionStatus Abort();
    }
和回调:

[ServiceContract]
    public interface IClientCallback
    {
        [OperationContract(IsOneWay = false)]
        string GetUserInput(string message, string information, bool isPause);

        [OperationContract(IsOneWay = true)]
        void OutputAvailable(OutputAvailableEventArgs args);

        [OperationContract(IsOneWay = true)]
        void ResultAvailable(ResultAvailableEventArgs args);

        [OperationContract(IsOneWay = true)]
        void ExecutionStarted(ExecutionStartedEventArgs args);

        [OperationContract(IsOneWay = true)]
        void ExecutionEnded(ExecutionEndedEventArgs args);
    }
该服务正在执行一些工作和报告,但有需要报告的内容。 Args类用名称空间标记为
DataContract
。它们包含.Net本机类型(
int
string
DateTime

我创建了一个测试应用程序,一切都很好(从请求服务执行到
ExecutionStarted
的时间称为~1秒)

在现有应用程序中创建客户端时,存在两个问题:

  • 缓慢-从
    Execute()
    ExecutionStarted()
    大约1分钟
  • 最后一个调用--
    ExecutionEnded
    ——根本没有发生。发生了什么事?最后一个
    OutputAvailable
    调用将发生。在调试期间,我看到服务调用了
    ExecutionEnded
    方法,但是在客户端调用的是
    OutputAvailable
    (应该在更早的时候调用,而不是调用finish方法)
  • 我在测试客户机和实际应用程序中使用相同的测试

    一些代码可能会有所帮助,我希望:

    服务

    类别声明:

      [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Reentrant)]
            public class ExecutionService : IExecutionService
    
    public ExecutionStatus Execute(string path)
            {
                lock (locker)
                {
                    var tempClient = OperationContext.Current.GetCallbackChannel<IClientCallback>();
                    if (client == null)
                        client = tempClient;
                    else if (client != null && client != tempClient)
                    {
                        throw new FaultException(new FaultReason("Execution Service is busy processing a request."));
                    }
                    else if (tempClient == null)
                        throw new FaultException(new FaultReason("No client found, execution is aborted."));
                    Log.InfoFormat("client: "+ DateTime.Now);
                    Log.InfoFormat(client == null ? "null" : client.ToString());
                }
                ((IContextChannel)client).OperationTimeout = new TimeSpan(0,3,0);
                Task<ExecutionStatus> executionTask = Task.Factory.StartNew(() => HandleExecution(path));
                return executionTask.Result;
    }
    
    就在“execute”方法返回之前,稍后我会得到:

    A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.dll
    A first chance exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in System.ServiceModel.dll
    A first chance exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in System.ServiceModel.dll
    A first chance exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in System.ServiceModel.dll
    A first chance exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in System.ServiceModel.dll
    
    这在我的测试应用程序中不会发生。
    知道这里怎么了吗

    编辑
    我想我知道出了什么问题,只是不知道如何解决。问题是我真正的应用程序是
    WPF
    ,它在使用
    WCF
    时存在一些问题。我尝试切换到
    NetTcpBinding
    ,但没有效果。我希望有其他建议

    编辑2
    对于
    WPF
    问题,您应该在回调实现中添加以下内容:

    [CallbackBehavior(UseSynchronizationContext = false)]
    
    (感谢您提供答案。)
    现在我仍然面临一个无响应的
    WPF
    客户端,但与服务的连接没有挂起。我希望有更多的建议

    编辑3

    现在只有一个方法没有在客户端上被调用。连接处于活动状态(之后还有其他调用),该方法没有做任何特殊的操作。

    我不知道您是如何设置服务的,但是您是否使用异步方法调用该服务的?否则,我建议您实现这一点。您的服务是静态的,因此这也可能是问题所在,当您在其他设备上运行它时,链接将无法工作。至于序列化错误,我无能为力

    我想每个人都会时不时地碰到那些WTF。
    我无法解释解决方案背后的逻辑,但解决方案本身非常简单:

  • 在服务解决方案中,重命名有问题的方法(在
    ICallback
    界面中)
  • 重新编译,并更新和重新编译有问题的应用程序
  • 运行应用程序时,突然调用该方法
  • 再次将该方法重命名为原始名称

  • 我不知道你所说的异步方法是什么意思。我正在使用服务接口中公开的方法。另外,我不确定静态服务是什么意思(我是新来的
    WCF
    )。请查看我的edit.soury我不清楚,我的意思是您指向服务的链接是静态的,这可能会解决您的上一个问题,至于异步部分,请使用此链接访问您的web服务。我找到了一个描述异步回调的链接[link]
    A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in System.Runtime.Serialization.dll
    A first chance exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in System.ServiceModel.dll
    A first chance exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in System.ServiceModel.dll
    A first chance exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in System.ServiceModel.dll
    A first chance exception of type 'System.ServiceModel.Dispatcher.NetDispatcherFaultException' occurred in System.ServiceModel.dll
    
    [CallbackBehavior(UseSynchronizationContext = false)]