我正在尝试使用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();
}));
}
}
非常感谢。
答案 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();
}));
}
}