问题
I am trying to take my first steps into IPC and the WCF, and so far, I'm falling flat on my face. I have a Winforms application that I would like to instrument somewhat for remote callers. The winforms application has most of its business logic confined to a singleton that takes care of all the background work. I would like to expose some of the functionality through an IPC mechanism. WCF seems like the way forward, so I started out with that.
What I tried is adding a WCF Service Library project to my solution, through which I would like to expose some calls. When I start the Winforms project in the VS debugger, it runs as normal, and the WcfSvcHost starts up. I can communicate to the WCF service with the WcfTestClient.
However, when I try to access the singleton holding the code I would like to communicate with, it seems like I am getting a new singleton object. Clearly, I'm doing it wrong; what I guess is happening is that the service runs in a different process, so there is no real shared code, and hence no shared singleton.
I'm not sure how I should continue. Is my choice of using WCF for IPC the wrong one? Should I integrate the WCF endpoints in the Winforms application? Is what I'm trying even feasible?
EDIT: I figured this was so high-level, and also so simple that any code sample would be useless. I think I was wrong. So some code:
In the WinForms assembly:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
label1.Text = MySingleton.Instance.InitedAt.ToString();
}
}
public class MySingleton
{
private static MySingleton instance = new MySingleton();
private DateTime inited;
private MySingleton()
{
this.inited = DateTime.Now;
}
public static MySingleton Instance
{
get
{
return instance;
}
}
public DateTime InitedAt
{
get
{
return this.inited;
}
}
}
In the WCFServiceLibrary assembly:
[ServiceContract]
public interface IApplicationProbe {
[OperationContract]
string DoesItWork();
[OperationContract]
string SingletonInited();
}
public class ApplicationProbe : IApplicationProbe {
public string DoesItWork(){
return "Why yes, yes it does";
}
public string SingletonInited(){
return MySingleton.Instance.InitedAt.ToString();
}
}
when I query SingletonInited
through the WcfTestClient, I get an InitedAt which is not the same DateTime as the instatiation of the winforms singleton.
Edit2:
I have this code running as is (with the auto-generated scaffolding around the Winforms stuff). The label on the form displays a different time than the time returned from the WCF call, demonstrating it is a different instance.
回答1:
I assume you're using your singleton class as a service (it implements a contract). I suggest you develop a WCF contract and a service, which will make calls to your singleton instead.
So you'll have something like this:
public class YourImpportantSingleton
{
public YourImpportantSingleton Instance { get; set; }
public void DoSeriousBusiness(){...}
}
[ServiceContract]
public interface IYourContract
{
void YourRemoteAction();
}
public class YourService : IYourContract
{
public void YourRemoteAction()
{
YourImportantSingleton.Instance.DoSeriousBusiness();
}
}
UPD: Ok, just realized, that you might not be using self-hosting in a winforms application, sorry for that waste of time.
Your options would be then either host a service with ServiceHost
in your forms application or host a service separately (with IIS, for example) and make this service a keeper of your singleton. You'll have to change your forms application to call separate service, as it holds the state now, of course.
回答2:
The problem here was that WCF Service Host was hosting the service, rather than the application itself. This caused the application to run in a seperate ApplicationDomain, which in turn caused a new singleton to be created. Switching to self-hosting solved the problem.
来源:https://stackoverflow.com/questions/11670896/exposing-a-winforms-application-internals-through-wcf