WCF - 如何在开始和结束呼叫之间保持频道/代理

时间:2011-03-29 11:12:46

标签: wcf channelfactory

我正在尝试使用ChannelFactory来调用异步服务。

我不确定的是如何最好地保持对通道的引用 - 在调用BeginSave和EndSave之间(在回调方法中)。

我目前正在通过将其分配给实例变量来实现这一点,但这似乎并不理想。我只希望频道在呼叫的生命周期中存在(我认为这是最好的做法,即打开,使用它,关闭它)。我还想确保关闭正确的频道,可能存在不止一个频道的情况。

关于如何做到这一点的任何例子都会很棒。

这是我的代码:

public partial class MyForm : Form
{

    ICompanyService m_Channel;

    public MyForm()
    {
        InitializeComponent();

    // ChannelProvider is a class I've created which returns a channel created by the ChannelFactory
        ChannelProvider<ICompanyService> channelProvider = new ChannelProvider<ICompanyService>();
        m_Channel = channelProvider.GetChannel();
    }

    private void OnSaveButtonClickAsync(object sender, EventArgs e)
    {
        Company company = new Company();
        company.BranchId = "A1";
        company.CompanyName = "A1 LTD";

        m_Channel.BeginSave(
            company, 
            new AsyncCallback(OnSaveCallback), 
            null);

        StatusLabel.Text = "Saving...";
    }

    private void OnSaveCallback(IAsyncResult ar)
    {
        int result = m_Channel.EndSave(ar);

        Invoke(
            new MethodInvoker(delegate()
            {
               StatusLabel.Text = result.ToString(); 
            }));
    }
}

非常感谢。

2 个答案:

答案 0 :(得分:0)


很遗憾在这件事上回复你。我认为你遇到的一个问题是你没有正确地实例化你的代理。不确定你的channelprovider做了什么,但创建自己的频道非常简单,可能不需要包装器。

我尝试使用旧计算器服务示例进行简单测试,发现我保持通道打开没有任何困难。

首先我创建了两个字段......

    private ChannelFactory<ICalculator> m_Factory;
    private ICalculator m_Proxy;

然后使用配置文件中的客户端配置在构造函数中实例化工厂。

    m_Factory = new ChannelFactory<ICalculator>("calc");

然后在调用服务时,我创建了我的代理并执行异步方法。一旦调用返回,我将代理转换为ICommunicationObject,它给了我通道的状态。您应该看到您调用的代理仍处于打开状态。然后你应该可以关闭它。

    void OnBegin(object sender, EventArgs e)
    {
        m_Proxy = m_Factory.CreateChannel();
        m_Proxy.BeginAdd(2, 3, OnCompletion, null);

        // Do other stuff...
    }

    void OnCompletion(IAsyncResult result)
    {
        int sum = m_Proxy.EndAdd(result);
        result.AsyncWaitHandle.Close();

        ICommunicationObject channel = (ICommunicationObject)m_Proxy;
        if (channel.State == CommunicationState.Opened)
            channel.Close();
    }

希望这有帮助。

答案 1 :(得分:0)

我在Juval Lowy的WCF书中找到了答案。使用我的原始示例,可以按如下方式重写:

公共部分类MyForm:表单 {

public MyForm()
{
    InitializeComponent();
}

private void OnSaveButtonClickAsync(object sender, EventArgs e)
{
    Company company = new Company();
    company.BranchId = "A1";
    company.CompanyName = "A1 LTD";

    // ChannelProvider is a class I've created which returns a channel created by the ChannelFactory
    ChannelProvider<ICompanyService> channelProvider = new ChannelProvider<ICompanyService>();
    channel = channelProvider.GetChannel();

    channel.BeginSave(
        company, 
        new AsyncCallback(OnSaveCallback), 
        channel);

    StatusLabel.Text = "Saving...";
}

private void OnSaveCallback(IAsyncResult ar)
{
    int result = m_Channel.EndSave(ar);

    IContextChannel contextChannel = (IContextChannel)ar.AsyncState;
    contextChannel.Close();

    Invoke(
        new MethodInvoker(delegate()
        {
           StatusLabel.Text = result.ToString(); 
        }));
}

}