我目前正在开发一个wcf发布订阅服务。在我的Windows窗体应用程序中,我有一个尝试订阅该服务的“连接”按钮。代码如下
WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding;
string clientcallbackaddress = binding.ClientBaseAddress.AbsoluteUri;
clientcallbackaddress += Guid.NewGuid().ToString();
binding.ClientBaseAddress = new Uri(clientcallbackaddress);
InstanceContext site = new InstanceContext(null, new mainForm(backgroundFormObject));
PostingContractClient client = new PostingContractClient(site);
client.Subscribe();
MessageBox.Show("Service has been connected!", "Connected");
至于异常处理,这就是我所做的,
try
{
//refer to codes above
}
catch (EndpointNotFoundException)
{
MessageBox.Show("WCF Service has not been started.", "Error");
}
catch (CommunicationException)
{
MessageBox.Show("Error");
}
如果我的服务未激活,单击“连接”按钮后,它将在发送第一个错误“WCF服务尚未启动”之前加载一段时间。 ,之后我激活了服务,单击“连接”按钮向我显示第二个错误,即使我的服务处于打开状态,也是CommunicationException。
知道如何解决这个问题吗?
错误的错误消息
通信对象System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于Faulted状态。
答案 0 :(得分:3)
这里的问题是前一个呼叫出错并使通信信道处于故障状态。因此在关闭之前不能使用它。
您需要捕获任何错误并清理并在故障状态下进行通道。
这是我们使用的一些标准代码,在您的情况下,您可能不想关闭频道。
可能是因为频道已经超时,所以频道处于故障状态。
try
{
client.Subscribe();
}
catch (Exception exception)
{
if (client != null)
{
client.Abort();
}
throw;
}
finally
{
if (client != null)
{
client.Close();
}
}
答案 1 :(得分:1)
我对上面的代码有点困惑,并尝试在评论中解释:
// The client seems to be initialized by that time
WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding;
...
// The client is initialized again
PostingContractClient client = new PostingContractClient(site);
无论如何,从错误中,您似乎已经发布了您尝试使用相同的对象进行后续调用,例如:
var client = new Client();
client.Subscribe(); // you get an exception here
client.Subscribe(); // channel is faulted, as you got an exception accessing it the first time
我在添加WCF服务作为参考时没有多少工作,我不知道实现细节。但是,与大量的汇编共享,我建议再次尝试创建Client
:
var client = new Client();
client.Subscribe(); // you get an exception here
client = new Client(); // I hope, another Channel is created, when calling the constructor.
client.Subscribe();
最好的问候。
答案 2 :(得分:1)
不确定这是否是您想要的,但从您的问题中我可以理解,这似乎就是您所需要的:
由于您需要变量在整个项目中可用,因此您可以在类的开头声明InstanceContext和Client。
InstanceContext site;
PostingContractClient client;
在form_Load方法中跟进,
site = new InstanceContext(null, new mainForm(backgroundFormObject));
client = new PostingContractClient(site);
最后在“连接”按钮中
try
{
site = new InstanceContext(null, new mainForm(backgroundFormObject));
var client = new PostingContractClient(site);
WSDualHttpBinding binding = (WSDualHttpBinding)client.Endpoint.Binding;
string clientcallbackaddress = binding.ClientBaseAddress.AbsoluteUri;
clientcallbackaddress += Guid.NewGuid().ToString();
binding.ClientBaseAddress = new Uri(clientcallbackaddress);
client.Subscribe();
MessageBox.Show("Service has been connected!", "Connected");
}
catch (EndpointNotFoundException)
{
if (client != null)
{
MessageBox.Show("WCF Service has not been started. Please try to manually connect again after the service has been started.", "Error");