首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >两个客户端之间的不同服务行为

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

Stack Overflow用户
提问于 2013-03-27 13:28:44
回答 2查看 1.1K关注 0票数 0

我有一个WCF服务,我需要将它合并到现有的应用程序中。

服务接口:

代码语言:javascript
运行
复制
[ServiceContract(CallbackContract = typeof(IClientCallback))]
    public interface IExecutionService
    {
        [OperationContract]
        ExecutionStatus Execute(string path);

        [OperationContract]
        ExecutionStatus Abort();
    }

以及回调:

代码语言:javascript
运行
复制
[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本机类型(intstringDateTime)。

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

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

  1. 慢度-从Execute()ExecutionStarted()大约1分钟。
  2. 最后一个电话-- ExecutionEnded --根本没有发生。会发生什么事?最后一次OutputAvailable调用会发生。在调试期间,我看到了调用ExecutionEnded方法的服务,但是在客户端调用的是OutputAvailable (应该更早地调用它,而不是代替finish方法)。

我在测试客户端和实际应用程序中使用相同的测试。

一些可能有用的代码,我希望:

服务

班级声明:

代码语言:javascript
运行
复制
  [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;
}

(确保我一次只有一个客户。我需要重入模式,这样就可以在服务的方法中使用回调。)

Client:创建到服务的连接:

代码语言:javascript
运行
复制
 var myBinding = new WSDualHttpBinding();
 var myEndpoint = new EndpointAddress("http://localhost:3050/ExecutionService");
 var myChannelFactory = new DuplexChannelFactory<IExecutionService>(this, myBinding, myEndpoint);
 service = myChannelFactory.CreateChannel();
 var executionStatus = service.Execute(@"C:\Users\nosh\Desktop\launcher.py"); 

如果有必要,我会发布更多的代码。

另一个问题是,在我真正的应用程序中,我得到了:

代码语言:javascript
运行
复制
A first chance exception of type 'System.TimeoutException' occurred in System.ServiceModel.dll
A first chance exception of type 'System.TimeoutException' occurred in mscorlib.dll

在“execute”方法返回之前,稍后我得到:

代码语言:javascript
运行
复制
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问题,您应该在回调实现中添加以下内容:

代码语言:javascript
运行
复制
[CallbackBehavior(UseSynchronizationContext = false)]

(感谢伊恩·林罗斯提供了答案这里。)

现在,我仍然面临一个没有响应的WPF客户端,但是到服务的连接没有挂起。我希望有更多的建议。

编辑3

现在,它只是一个没有在客户机上被调用的方法。连接是活动的(在它之后还有其他调用),这个方法没有做什么特别的事情。

EN

Stack Overflow用户

回答已采纳

发布于 2013-04-02 13:58:49

我想每个人都不得不不时地碰上这些东西。

我无法解释解决方案背后的逻辑,但解决方案本身很简单:

  1. 在服务解决方案中,重命名有问题的方法(在ICallback接口中)。
  2. 重新编译并更新和重新编译有问题的应用程序。
  3. 运行应用程序,方法就会突然被调用。
  4. 再次将该方法重命名为原始名称。
  5. 赢!
票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15660051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档