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

时间:2012-12-07 15:07:55

标签: c# .net wcf

所有,我已经扩展this tutorial来获取和反转在两个单独的WinForm应用程序中显示的字符串。但是,最终目标是让这个在WinForm应用程序之间工作,这些应用程序在彼此之间传递SQL。为了方便这一点,我扩展了这个例子,以下是我所拥有的

包含

的库.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;
    }
}

所以在'服务器'表格上,我做

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>();
}

哪里

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();
}

在客户端WinForm应用程序

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

并且在点击事件中我无法从服务器获取List<string>

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

我的问题是这有什么问题?

感谢您的时间。


编辑。我现在还根据以下评论更改了客户端代码

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();
}

这也会在点击事件中挂起。

1 个答案:

答案 0 :(得分:1)

您设置代码的方式是,您通过引用WcfInterface.Instance在客户端上创建WCF服务器。然后,您将从它所服务的同一个线程中调用它,从而导致应用程序锁定。

有很多方法可以解决这个问题。以下是一些想到的内容:

  • 在第一个WinForm应用程序中运行服务,然后使用visual studio中的“添加服务引用”功能来创建代理。请注意,您必须
  • 您仍然可以引用WCF合同的公共库,但是重新编写代码,这样您就不会在“客户端”WinForms应用程序中创建服务实例。