问题描述
|
我是WCF的新手,我正在尝试学习,但是我认为我在这里缺少重要的东西,我知道这一点,所以请保持友好。我正在使用一个已有的控制台应用程序,并且已经向其中添加了WCF主机,这是它的过于简化的版本,但是它应该可以帮您
namespace mynamespace
{
public class MyConsoleApp
{
static void Main(string[] args)
{
CreateRemoteDebugHost();
StartLongRunningMethods();
}
public static void StartLongRunningMethods()
{
LongRunningMethod1();
LongRunningMethod2();
}
public static void LongRunningMethod1()
{}
public static void LongRunningMethod2()
{}
public void CreateRemoteDebugHost()
{
ServiceHost host = new ServiceHost(typeof(RemoteDebug),new Uri(\"net.pipe://localhost\"));
host.AddServiceEndpoint(typeof(IRemoteDebug),new NetNamedPipeBinding(NetNamedPipeSecurityMode.None),\"PipeRemoteDebug\");
//Create mex
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpGetUrl = new Uri(\"http://localhost:8001/RemoteDebug\");
host.Description.Behaviors.Add(smb);
host.open();
}
}
[ServiceContract(SessionMode = SessionMode.required,CallbackContract = typeof(IRemoteDebugCallback))]
public interface IRemoteDebug
{
[OperationContract]
string Message(string message);
}
public interface IRemoteDebugCallback
{
[OperationContract(IsOneWay = true)]
void OnMessage(string callbackValue);
}
public class RemoteDebug : IRemoteDebug
{
public string Message(string message)
{
IRemoteDebugCallback callback = OperationContext.Current.GetCallbackChannel<IRemoteDebugCallback>();
callback.OnMessage(message);
return message;
}
}
}
如您所知,我正在尝试从长时间运行的静态方法内部将调试或状态消息发送回客户端。所有管道似乎都能正常工作,主机启动,我可以向我的客户端应用程序添加服务引用,但是当尝试从longrunningprocesses静态方法调用WCF回调时,麻烦就开始了。我似乎无法弄清楚如何正确地做到这一点。
令人非常困惑的是,我所看到的有关WCF和回调的几乎每个示例都假定您所做的一切都是在WCF主机本身的上下文中运行的,显然,在我的示例中并非如此。我知道我可能会继续,但是这全都错了,所以有人可以请我直接设置吗?任何帮助是极大的赞赏。
TIA!
解决方法
也可以通过app.config或手动创建客户端(不要与客户端程序混淆)(例如
public class MyClient: ClientBase<IRemoteDebug>
或ѭ2fused)。这应该将消息发送到客户端程序。我从上面的一些代码中使用DuplexClient的示例:
[CallbackBehaviorAttribute(UseSynchronizationContext = true)]
public class SubCallback : IRemoteDebug
{
public void Event(SomeClass evt)
{
// some handling code using:
//public delegate void EventCallbackHandler(SomeClass evt);
}
}
InstanceContext ctx = new InstanceContext(new SubCallback ());
MyClient _client = new MyClient(
ctx,new NetNamedPipeBinding(NetNamedPipeSecurityMode.None),new EndpointAddress(\"net.pipe://localhost/ServiceEndpointName\"));
另外,您可能希望将一些选项传递给您的服务,例如:
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.Single,ConcurrencyMode = ConcurrencyMode.Single)]
public class RemoteDebug : IRemoteDebug
{}
可能是造成您特定问题的很多原因,但这为我解决了问题。