简体   繁体   English

WCF基本WinForm应用程序通信问题

[英]WCF Basic WinForm App Communication Issue

All, I have extended this tutorial to get and reverse string displayed in two seperate WinForm applications. 所有,我已经扩展了本教程,以获取和反向显示在两个单独的WinForm应用程序中的字符串。 However, the end goal is to get this working between to WinForm apps that pass SQL between eachother. 但是,最终目标是使两者之间能够相互传递SQL的WinForm应用程序之间能够正常工作。 To facilitate this I have extended this example and the following is what I have 为方便起见,我扩展了此示例,以下是我所拥有的

A library .dll containing 包含.dll的库

public class WcfInterface
{
    private static WcfInterface instance;
    private ServiceHost host;
    private const string serviceEnd = "Done";

    protected WcfInterface()
    {
    }

    public static WcfInterface Instance()
    {
        if (instance == null)
            instance = new WcfInterface();
        return instance;
    }

    public void OpenServiceHost<T, U>() 
    {
        host = new ServiceHost(typeof(U), new Uri[] { new Uri("net.pipe://localhost") });
        host.AddServiceEndpoint(typeof(T), new NetNamedPipeBinding(), serviceEnd);
        host.Open();
    }

    public void CloseServiceHost<T>()
    {
        host.Close();
    }

    public T AddListnerToServiceHost<T>()
    {
        ChannelFactory<T> pipeFactory = 
            new ChannelFactory<T>(new NetNamedPipeBinding(), 
                                         new EndpointAddress(String.Format("net.pipe://localhost/{0}", 
                                                                                      serviceEnd)));
        T pipeProxy = pipeFactory.CreateChannel();
        return pipeProxy;
    }
}

So on the 'server' form, I do 所以在“服务器”形式上

private void Form1_Load(object sender, EventArgs e)
{
    List<string> sqlList = new List<string>();
    foreach (string line in this.richTextBoxSql.Lines)
        sqlList.Add(line);
    SqlInfo sqlInfo = new SqlInfo(sqlList);
    WcfInterface wcfInterface = WcfInterface.Instance();
    wcfInterface.OpenServiceHost<ISqlListing, SqlInfo>();
}

Where 哪里

public class SqlInfo : ISqlListing
{
    private List<string> sqlList;
    public SqlInfo(List<string> sqlList)
    {
        this.sqlList = sqlList;
    }

    public List<string> PullSql()
    {
        return sqlList;
    }
}

[ServiceContract]
public interface ISqlListing
{
    [OperationContract]
    List<string> PullSql();
}

In the client WinForm app 在客户端WinForm应用中

private ISqlListing pipeProxy;
public Form1()
{
    InitializeComponent();
    WcfInterface wcfInterface = WcfInterface.Instance();
    pipeProxy = wcfInterface.AddListnerToServiceHost<ISqlListing>();
}

and on the click event I attampt to get the List<string> from the server 在单击事件上,我尝试从服务器获取List<string>

private void button1_Click(object sender, EventArgs e)
{
    this.richTextBoxSql.Text = pipeProxy.PullSql().ToString(); // Code hangs here.
}

My question is what is wrong with this? 我的问题是这怎么了?

Thanks for your time. 谢谢你的时间。


Edit. 编辑。 I have now also changed the client code according to comments as follows 我现在还根据注释更改了客户端代码,如下所示

private ISqlListing pipeProxy { get; set; }
private const string serviceEnd = "Done";

public Form1()
{
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
    this.richTextBoxSql.Text = pipeProxy.PullSql().ToString(); 
 }

private void Form1_Load(object sender, EventArgs e)
{
    ChannelFactory<ISqlListing> pipeFactory =
    new ChannelFactory<ISqlListing>(
      new NetNamedPipeBinding(),
      new EndpointAddress(
         String.Format("net.pipe://localhost/{0}", serviceEnd)));

    pipeProxy = pipeFactory.CreateChannel();
}

this also hangs on the click event. 这也挂在点击事件上。

The way you have the code set up, you are creating a WCF server on the client by referencing WcfInterface.Instance. 设置代码的方式是,通过引用WcfInterface.Instance在客户端上创建WCF服务器。 You are then calling it from the same thread that it is being served on, causing your application to lock up. 然后,您要从与其在同一线程上调用该线程,从而导致您的应用程序锁定。

There are a number of ways to get around this. 有许多方法可以解决此问题。 Here are a few that come to mind: 这里有一些想法:

  • Get the service running in your first WinForm app, then use the "Add Service Reference" functionality in visual studio to create your proxies. 使服务在您的第一个WinForm应用程序中运行,然后使用Visual Studio中的“添加服务参考”功能来创建代理。 Note that you'll have to 请注意,您必须
  • You can still reference a common library for the WCF contracts, but rework your code so that you're not creating an instance of the service in your "client" WinForms app. 您仍然可以引用WCF合同的公共库,但是需要重新编写代码,以免在“客户端” WinForms应用程序中创建服务实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM