为什么我的 WCF 服务在 10 次调用后返回故障异常并超时?

发布于 2024-07-25 06:34:20 字数 1346 浏览 6 评论 0原文

我有一个 WCF 服务,有时必须返回错误。 由于某种原因,对我的服务的调用开始超时并出现以下错误: “请求通道在 00:00:59.8906201 之后等待回复时超时。增加传递给 Request 调用的超时值或增加 Binding 上的 SendTimeout 值。分配给此操作的时间可能是更长的超时时间。”

检查问题后,出现了一种模式:当服务返回故障 10 次时,超时开始。 因此,我创建了一个测试服务,其实现方式是:

public string GetData(int value)
{
    throw new FaultException("A testerror occured");
}

和一个测试客户端:

   protected void RunTestGetData()
    {
        using (TestServiceReference.Service1Client client
            = new WSPerformanceTester.TestServiceReference.Service1Client())
        {
            try
            {
                client.GetData(1);
                client.Close();
                outputWriter.WriteLine(string.Format("Call run in thread {0}: GetData()", Thread.CurrentThread.ManagedThreadId));
                outputWriter.Flush();
            }
            catch (Exception e)
            {
                client.Abort();
                client.Close();
                outputWriter.WriteLine(string.Format("Error occured in thread {0}: GetData(): {1}", Thread.CurrentThread.ManagedThreadId, e.Message));
                outputWriter.Flush();
            }
        }
    }

只有当服务返回FaultException 时,才会发生这种情况。 如果我抛出一个正常的异常,该服务能够在第 10 次调用后继续运行。 显然,我想很好地包装我的异常,所以仅仅抛出正常的异常并不是一个真正的选择。

为什么我会遇到这些超时异常? 预先感谢您的任何帮助..

I have a WCF service that sometimes has to return a Fault. For some reason, the calls to my service begins to time out with the following error:
"The request channel timed out while waiting for a reply after 00:00:59.8906201. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout."

After examining the problem, a pattern emerged: When the service had returned a fault 10 times, the timeout starts. So I created a testservice implemented by:

public string GetData(int value)
{
    throw new FaultException("A testerror occured");
}

And a testclient:

   protected void RunTestGetData()
    {
        using (TestServiceReference.Service1Client client
            = new WSPerformanceTester.TestServiceReference.Service1Client())
        {
            try
            {
                client.GetData(1);
                client.Close();
                outputWriter.WriteLine(string.Format("Call run in thread {0}: GetData()", Thread.CurrentThread.ManagedThreadId));
                outputWriter.Flush();
            }
            catch (Exception e)
            {
                client.Abort();
                client.Close();
                outputWriter.WriteLine(string.Format("Error occured in thread {0}: GetData(): {1}", Thread.CurrentThread.ManagedThreadId, e.Message));
                outputWriter.Flush();
            }
        }
    }

This only happens, when the service is returning a FaultException. If I throw a normal exception, the service is able to continue running after the 10th call. Obviously, i would like to wrap my exceptions nicely, so just throwing normal exceptions is not a real option.

Why do I experience these timeout exceptions? Thanks in advance for any help..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

最美不过初阳 2024-08-01 06:34:21

我没有足够的观点来评论,所以新的回应...

自托管服务最多只允许 10 个并发连接 - 无论传输方式如何。 如果您在 IIS/WAS 内运行 WCF 服务,则不必担心这一点(除非您使用的是 XP/Vista,其中最大并发连接数也是 10)。

在这种情况下,故障异常和常规异常之间的差异可以解释您所看到的结果。

请记住,常规的未处理异常会使通道出现故障。 这样做时,我假设这会打开一个可用的连接。 当您返回故障时,它会自动对通道进行故障处理,因为它允许您对连接执行某些操作并在您的一端处理故障,因为它可能是“预期”故障,而未处理的异常则不会。

即使返回错误,您仍然需要 Abort() 连接。 此外,下面还有非托管资源,因此请务必在客户端/代理的调用者上实现 IDisposable。

I don't have enough points to comment, so new response...

Self hosted services only allow a max of 10 concurrent connections - no matter the transport. If you're running WCF services inside of IIS/WAS you shouldn't have to worry about this (unless you're on XP/Vista where the max concurrent connections is also 10).

Differences between a fault exception and a regular exception in this scenario can account for the result you're seeing.

Remember, a regular unhandled exception will fault the channel. In doing so I assume this opens up an available connection. When you return a fault, it won' automatically fault the channel because it allows you to do something with the connection and handle the fault on your end because it is a possible "expected" fault whereas an unhandled exception would not be.

Even when you return a fault, you still need to Abort() the connection. Also, underneath there are unmanaged resources so be sure to implement IDisposable on your clients/proxy's callers.

浮世清欢 2024-08-01 06:34:21

我认为这可能是因为 WCF 服务的默认行为是 10 个并发会话。
发生故障异常后是否保持连接打开? 您可以尝试在BehaviorConfiguration(ServiceThrotdling > MaxConcurrentSessions)中更改此值,看看是否会发生任何变化。
我建议您使用 Microsoft 服务配置编辑器来检查默认设置的其他值。 (MSDN

希望这有帮助...

I think this might be because the default behavior of a WCF service is 10 concurrent sessions.
Are you keeping the connections open after the FaultExceptions occur? You can try to alter this value in the BehaviorConfiguration (ServiceThrottling > MaxConcurrentSessions) and see if that changes anything.
I suggest you use the Microsof Service Configuration Editor to check out what other values are set by default. (MSDN)

hope this helps...

情释 2024-08-01 06:34:21

我面临着同样的问题。 仔细观察发现,在完成对 Web 服务的调用后,我没有关闭 Web 服务客户端。 一旦我这样做了,即使在对 Web 服务进行 10 次方法调用之后,它也没有失败。 请参阅下面的示例。

WebServiceClient svcClient = new WebServiceClient();

string returnValue = svcClient.GetDocumentName(fileId);

svcClient.Close();

正确模式:

using(WebServiceClient svcClient = new WebServiceClient())
{
   return svcClient.GetDocumentName(fileId);
}

ClientBase 实现 IDisposable,它在 Dispose 方法中调用 Close()

I was facing the same issue. A closer look revealed that I was not closing the webservice client after I was done making the calls to the webservice. Once I did that, it did not fail even after 10 method calls to the webservice. See the example below.

WebServiceClient svcClient = new WebServiceClient();

string returnValue = svcClient.GetDocumentName(fileId);

svcClient.Close();

proper pattern:

using(WebServiceClient svcClient = new WebServiceClient())
{
   return svcClient.GetDocumentName(fileId);
}

ClientBase implements IDisposable, which calls Close() within the Dispose method.

阳光①夏 2024-08-01 06:34:21

我在这里可能是错的,但我认为这与 WCF 服务的托管有关。

因为它可能无法及时响应请求。

例如,Windows XP 上的 IIS 可以同时回复 5 个(我现在不太确定)请求。 如果发出更多请求,则会进入队列。

我相信它可能会丢失请求,并且这样做而不是处理它们,因为您的测试实际上除了抛出异常之外什么也不做。

I might be wrong here, but I think it has something to do with the hosting of the WCF service.

Because it might not be able to respond to the request in a timely fashion.

IIS on Windows XP, for instance, can reply to 5 (and I'm not so sure about it right now) simultaneous requests. If more requests are made, it go to a queue.

And I believe it might be loosing the requests, and doing so, not processing them, as your test actually do nothing but throw an exception.

失眠症患者 2024-08-01 06:34:21

显然,客户端代码应如下所示:

protected void RunTestGetData()
{
    TestServiceReference.Service1Client client
        = new WSPerformanceTester.TestServiceReference.Service1Client()
    try
    {
        client.GetData(1);
    }
    catch (FaultException e)
    {
        //Handle fault
    }
    try
    {
        if (client.State != System.ServiceModel.CommunicationState.Faulted)
        {
            client.Close();
        }
    }
    catch(Exception e)
    {
        outputWriter.WriteLine("Error occured in Client.Close()");
        outputWriter.Flush();
        client.Abort();
    }
}

调用 client.Abort() 应该始终是最后的手段。

Apparently, the client code should be as follows:

protected void RunTestGetData()
{
    TestServiceReference.Service1Client client
        = new WSPerformanceTester.TestServiceReference.Service1Client()
    try
    {
        client.GetData(1);
    }
    catch (FaultException e)
    {
        //Handle fault
    }
    try
    {
        if (client.State != System.ServiceModel.CommunicationState.Faulted)
        {
            client.Close();
        }
    }
    catch(Exception e)
    {
        outputWriter.WriteLine("Error occured in Client.Close()");
        outputWriter.Flush();
        client.Abort();
    }
}

Calling client.Abort() should always be a last resort.

稚气少女 2024-08-01 06:34:21

尝试我的 WCF 服务模型客户端 API,看看是否会出现相同的结果。 我认为客户端代码中有问题...

代码

PPT

另外,在客户端和服务器上启用详细 WCF 日志记录...

Try my WCF Service Model Client API and see if the same results occur. I am think something is not right in the client code...

The Code

The PPT

Also, enable verbose WCF logging on both the client and server...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文