0

总而言之,我已经扩展了本教程以获取和反转显示在两个单独的 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();
}

这也挂在点击事件上。

4

1 回答 1

1

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

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

  • 让服务在您的第一个 WinForm 应用程序中运行,然后使用 Visual Studio 中的“添加服务引用”功能来创建您的代理。请注意,您必须
  • 您仍然可以为 WCF 合同引用一个公共库,但重新编写您的代码,这样您就不会在您的“客户端”WinForms 应用程序中创建服务的实例。
于 2012-12-07T15:19:22.900 回答