WCF-如何在开始和结束调用之间保持通道/代理
我正在尝试使用ChannelFactory调用异步服务 我不确定的是,在调用BeginSave和EndSave(在回调方法中)之间,如何最好地保持对通道的引用 我目前通过将其分配给实例变量来实现这一点,但这似乎并不理想。我只希望该频道在通话期间存在(我认为这是最佳实践,即打开、使用、关闭)。我还想确保我关闭了正确的频道,可能存在多个频道的情况 任何关于如何最好地做到这一点的例子都是非常好的 这是我的密码:WCF-如何在开始和结束调用之间保持通道/代理,wcf,channelfactory,Wcf,Channelfactory,我正在尝试使用ChannelFactory调用异步服务 我不确定的是,在调用BeginSave和EndSave(在回调方法中)之间,如何最好地保持对通道的引用 我目前通过将其分配给实例变量来实现这一点,但这似乎并不理想。我只希望该频道在通话期间存在(我认为这是最佳实践,即打开、使用、关闭)。我还想确保我关闭了正确的频道,可能存在多个频道的情况 任何关于如何最好地做到这一点的例子都是非常好的 这是我的密码: public partial class MyForm : Form { ICo
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();
}));
}
}
公共部分类MyForm:Form
{
i公司服务m_频道;
公共MyForm()
{
初始化组件();
//ChannelProvider是我创建的一个类,它返回由ChannelFactory创建的通道
ChannelProvider ChannelProvider=新的ChannelProvider();
m_Channel=channelProvider.GetChannel();
}
私有void OnSaveButtonClickAsync(对象发送方,事件参数e)
{
公司=新公司();
company.BranchId=“A1”;
company.CompanyName=“A1有限公司”;
m_Channel.BeginSave(
公司,
新建异步回调(OnSaveCallback),
无效);
StatusLabel.Text=“正在保存…”;
}
私有void OnSaveCallback(IAsyncResult ar)
{
int result=m_Channel.EndSave(ar);
援引(
新的MethodInvoker(委托()
{
StatusLabel.Text=result.ToString();
}));
}
}
非常感谢。很抱歉,我们没有及时回复您。我认为您的问题之一是没有正确地实例化代理。不确定channelprovider做什么,但创建自己的频道非常简单,可能不需要包装器 我使用旧的calculator服务示例尝试了一个简单的测试,发现保持频道开放没有任何困难 首先我创建了两个字段
private ChannelFactory<ICalculator> m_Factory;
private ICalculator m_Proxy;
希望这有帮助。我在朱瓦尔·洛伊的WCF书中找到了答案。使用我的原始示例,可以将其改写如下: 公共部分类MyForm:Form {
publicmyform()
{
初始化组件();
}
私有void OnSaveButtonClickAsync(对象发送方,事件参数e)
{
公司=新公司();
company.BranchId=“A1”;
company.CompanyName=“A1有限公司”;
//ChannelProvider是我创建的一个类,它返回由ChannelFactory创建的通道
ChannelProvider ChannelProvider=新的ChannelProvider();
channel=channelProvider.GetChannel();
BeginSave频道(
公司,
新建异步回调(OnSaveCallback),
渠道);
StatusLabel.Text=“正在保存…”;
}
私有void OnSaveCallback(IAsyncResult ar)
{
int result=m_Channel.EndSave(ar);
IContextChannel contextChannel=(IContextChannel)ar.AsyncState;
contextChannel.Close();
援引(
新的MethodInvoker(委托()
{
StatusLabel.Text=result.ToString();
}));
}
}出于好奇,你为什么要保留频道?你想用它打另一个电话吗?我不明白你想做什么。这样我就可以调用服务的EndSave方法,然后在OnSaveCallback方法中关闭频道。例如,如果我同步调用,我可以用相同的方法完成所有这些,而不需要实例/成员变量。我真正想要的是这样做,而不使用成员/实例变量在begin和end调用之间保留对代理的引用。在重读了朱瓦尔·洛伊的书之后,我想我现在找到了这个。我很快会发布一个完整的解释。
m_Factory = new ChannelFactory<ICalculator>("calc");
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();
}
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();
}));
}