我有一个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;
}
(确保我一次只有一个客户。我需要重入模式,这样就可以在服务的方法中使用回调。)
Client:创建到服务的连接:
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");
如果有必要,我会发布更多的代码。
另一个问题是,在我真正的应用程序中,我得到了:
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”方法返回之前,稍后我得到:
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
现在,它只是一个没有在客户机上被调用的方法。连接是活动的(在它之后还有其他调用),这个方法没有做什么特别的事情。
发布于 2013-04-02 13:58:49
我想每个人都不得不不时地碰上这些东西。
我无法解释解决方案背后的逻辑,但解决方案本身很简单:
ICallback
接口中)。https://stackoverflow.com/questions/15660051
复制相似问题