开启/关闭网络服务

4
我有一个服务。我们向该服务发送记录。然而,当我们发送太多记录(3,000条)时,服务会超时。我的想法是将记录拆分并在每1,000条记录后打开服务,再关闭服务。
然而,我遇到了一个错误:
{"Cannot access a disposed object.\r\nObject name: 'System.ServiceModel.Channels.ServiceChannel'."}

这是我的代码:

ServiceClient client = new ServiceClient();
foreach (Record rc in creditTransactionList)
{
    //if we are not on the last one...
    if (currentTransCount < totalTransCount)
    {
        //Current batch count is less than 1,000
        if (currentBatchCount <= amountPerBatch)
        {
            currentBatchCount++;
            if (rc != null)
                client.RecordInsert(rc);
        }
        //Current batch count is 1,000
        if (currentBatchCount == amountPerBatch)
        {
            currentBatchCount = 0;
            client.Close();
            client.Open();
        }
        //Increment Total Counter by 1
        currentTransCount++;
    }
    else
    {
        currentBatchCount++;
        if (rc != null)
            client.RecordInsert(rc);
        client.Close();
    }
}

amountPerBatch = 1000;
totalTransCount = ACHTransactionList.Count();
currentBatchCount = 0;
currentTransCount = 1;

foreach (Record rc in ACHTransactionList)
{
    //if we are not on the last one...
    if (currentTransCount < totalTransCount)
    {
        //Current batch count is less than 1,000
        if (currentBatchCount <= amountPerBatch)
        {
            currentBatchCount++;
            if (rc != null)
                client.RecordInsert(rc);
        }
        //Current batch count is 1,000
        if (currentBatchCount == amountPerBatch)
        {
            currentBatchCount = 0;
            client.Close();
            client.Open();
        }
        //Increment Total Counter by 1
        currentTransCount++;
    }
    else
    {
        currentBatchCount++;
        if (rc != null)
            client.RecordInsert(rc);
        client.Close();
    }
}

我创建了一个样例控制台应用程序以执行此操作,但是当我将其实际并入实际项目和实际服务时,出现错误。请问你能否帮我找出问题所在?我的猜测是client.open和client.close有问题。非常感谢您的任何帮助!

1
我怀疑你的服务客户端只能使用一次,尝试为每个批次创建一个新的客户端。 - Ben Robinson
3个回答

8

我会尝试更像这样的方式... 请注意,您应该始终.Dispose()客户端。此外,如果发生错误,则.Close()不再适用于客户端,而是必须.Abort()它。

ServiceClient client = new ServiceClient();
try
{
  foreach(...)
  {
    ...
    //Current batch count is 1,000
    if (currentBatchCount == amountPerBatch)
    {
        currentBatchCount = 0;
        client.Close();
        client = new ServiceClient();
    }
    ...
  }
}
finally
{
  if(client.State == CommunicationState.Faulted)
    client.Abort();
  else
    client.Close();
}

友情提示 - 你不能调用 client.Dispose(),因为该方法不可用。 - dyslexicanaboko
@dyslexicanaboko - 这是错误的。WCF客户端的类型为System.ServiceModel.ClientBase<>,它实现了IDisposable接口,因此具有.Dispose()方法。这是该方法的MSDN页面:http://msdn.microsoft.com/en-us/library/bb340248(v=vs.110).aspx - CodingWithSpike
不是针对你,但请去编写那段代码并尝试编译,你会得到一个语法错误。这是我说这句话的唯一原因。 - dyslexicanaboko
@dyslexicanaboko - 哦,看起来目前ClientBase显式实现了Dispose,所以你是正确的,它不能像我的代码中那样被调用。我的代码示例基于我当时在生产中使用的东西,所以我很确定它曾经是可调用的。也许自从这个答案创建以来,Microsoft在过去的3年里改变了ClientBase?如果我记得正确的话,这是为.NET 3.5编写的。 - CodingWithSpike
哦,是的,他们改变了很多。我花了不少时间试图弄清楚为什么我的生产代码在基础架构将 .Net 框架从 4 升级到 4.5 后神奇地崩溃,而没有进行任何发布 - 微软将许多命名空间从一个程序集移动到另一个程序集,这使得你必须更新你的引用,无论你是否计划这样做。这只是一些改变的例子,但是确实发生了很多变化:D - dyslexicanaboko
嗨,来自2017年。这仍然是最好的方法吗?还是微软已经实现了一些新的内置函数? - Drag and Drop

1

client.Close会释放对象。在此之后,client.Open将始终抛出错误。 您需要使用new ServiceClient();初始化客户端。


我尝试通过执行ServiceClient client = new ServiceClient();来初始化客户端,但是我收到了一个错误:无法在此范围内声明名为'client'的局部变量,因为它会赋予'client'不同的含义,而'client'已经在“父级或当前”范围中用于表示其他内容 - Turp

0
我所做的是检查客户端的状态并在必要时重置它:
if (wsClient.State.Equals(CommunicationState.Faulted) || wsClient.State.Equals(CommunicationState.Closed) || wsClient.State.Equals(CommunicationState.Closing))
                {
                    wsClient = new ServiceClient();
                }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接