C# 通过WCF公开winforms应用程序内部
我正试图迈出我进入IPC和WCF的第一步,到目前为止,我的脸都快塌下来了。我有一个Winforms应用程序,我想为远程调用者提供一些工具。winforms应用程序的大部分业务逻辑都被限制在一个处理所有后台工作的单例中。我想通过IPC机制公开一些功能。WCF似乎是前进的方向,所以我从这开始 我尝试的是在我的解决方案中添加一个WCF服务库项目,通过它我想公开一些调用。当我在VS调试器中启动Winforms项目时,它正常运行,WcfSvcHost启动。我可以使用WcfTestClient与WCF服务通信 然而,当我试图访问包含我想要与之通信的代码的singleton时,似乎我得到了一个新的singleton对象。显然,我做错了;我想现在发生的是,服务运行在不同的进程中,因此没有真正的共享代码,因此没有共享的单例 我不知道该怎么继续。我对IPC使用WCF的选择是错误的吗?我应该在Winforms应用程序中集成WCF端点吗?我所尝试的是可行的吗 编辑:我认为这是一个很高层次的问题,也很简单,任何代码示例都是无用的。我想我错了。所以一些代码: 在WinForms程序集中:C# 通过WCF公开winforms应用程序内部,c#,visual-studio-2010,wcf,ipc,C#,Visual Studio 2010,Wcf,Ipc,我正试图迈出我进入IPC和WCF的第一步,到目前为止,我的脸都快塌下来了。我有一个Winforms应用程序,我想为远程调用者提供一些工具。winforms应用程序的大部分业务逻辑都被限制在一个处理所有后台工作的单例中。我想通过IPC机制公开一些功能。WCF似乎是前进的方向,所以我从这开始 我尝试的是在我的解决方案中添加一个WCF服务库项目,通过它我想公开一些调用。当我在VS调试器中启动Winforms项目时,它正常运行,WcfSvcHost启动。我可以使用WcfTestClient与WCF服务通
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;
}
}
}
[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();
}
}
在WCFServiceLibrary程序集中:
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;
}
}
}
[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();
}
}
当我通过WcfTestClient查询singletonited
时,我得到的InitedAt与winforms singleton的安装日期时间不同
编辑2:
我让这段代码按原样运行(使用围绕Winforms的自动生成的脚手架)。表单上的标签显示的时间与WCF调用返回的时间不同,表明它是不同的实例 我假设您将单例类用作服务(它实现了一个契约)。我建议您开发一个WCF合同和一个服务,它将呼叫您的单身汉 所以你会有这样的东西:
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:好的,刚刚意识到,您可能没有在winforms应用程序中使用自托管,很抱歉浪费时间
然后,您可以选择在表单应用程序中使用
ServiceHost
托管服务,或者单独托管服务(例如,使用IIS),并使此服务成为您的单身汉的守护者。当然,您必须将表单应用程序更改为调用单独的服务,因为它现在保持状态。这里的问题是WCF服务主机托管的是服务,而不是应用程序本身。这导致应用程序在一个单独的ApplicationDomain中运行,从而创建一个新的单例。切换到自托管解决了这个问题 我为我现在拥有的东西添加了一些代码,看起来很奇怪yours@Martijn,那么WCF不会创建你的单例的第二个实例(顺便说一句,你忘记了静态的),但它会创建你的服务类的instace。我忘记了这里的静态,只是修复了它们。我将运行我的示例代码,让您知道会发生什么。谢谢你的关注!在您的特定示例中,InitedAt将设置为第一个单例访问时间,因为w/out static constructor presentstatic
字段将被延迟初始化。我完成了代码并让它运行。(如果您愿意,我可以快速将整个解决方案树放到web上,以便您进行验证)。WCF调用显示的时间与表单showsIPC上的标签显示的时间不同,WCF通常使用命名管道完成。它当然得到支持;但是有很多开销。除了WCF之外,还有许多更高效的IPC方法。例如,内存映射文件。您是指WCF而不是WPF吗?这是第一个设置:首先让它工作,然后让它高效地工作。因为我还不能开始第一步,所以我还没有开始第二步,但我认为命名管道是一个很好的选择。我会查看内存映射文件,谢谢你的建议。是的,WCF,不是WPF。。。自动更正:)因为这主要不是关于大量的数据交换,而是关于让另一端的应用程序执行一些提升/工作,所以MMFs裸机样式似乎不如更易于管理/类型安全的WCF适合我。