简体   繁体   English

长时间运行会丢弃WCF [OperationContract(IsOneWay = true)]

[英]Disposing WCF with long running [OperationContract(IsOneWay = true)]

I've following service, defined as OneWay, because it's long running (a few minutes) and I can't wait when it finishes (it's used in ASP.NET application). 我正在跟踪被定义为OneWay的服务,因为它运行时间很长(几分钟),并且我迫不及待地想知道它的完成时间(在ASP.NET应用程序中使用了它)。

The problem is that if I call client.Dispose() after the service call, it blocks and after 60s timeout expires with exception. 问题是,如果我在服务调用之后调用client.Dispose(),它将阻塞,并且60s超时将异常终止。

How should I dispose the client in such scenario? 在这种情况下我应该如何处置客户? Increasing the timeout of the service isn't solution, because I can't wait so long time with the HTTP request of the web page, where it's used. 增加服务的超时时间不是解决方案,因为我迫不及待要使用网页的HTTP请求这么长时间。

[ServiceContract]
public interface IMyService
{        
    [OperationContract(IsOneWay = true)]
    void BeginRun();
}

var client = new MyServiceClient();
client.BeginRun();
client.Close(); //This leads to time-out, how and when to call it?

Thanks for tips. 感谢您的提示。

I would switch your binding to netMsmqBinding . 我将您的绑定切换为netMsmqBinding Then from your client your one-way calls will be instantaneous. 然后,您的客户将立即发出单向呼叫。

Long duration sends over http are problematic at best and complex to manage. 通过HTTP进行长时间发送充其量是有问题的,并且管理起来很复杂。 Sticking a queue in between will greatly simplify this operation. 将队列置于两者之间将大大简化此操作。

From your signiture, it seems like you don't need any sort of response. 从您的签名看来,您不需要任何回应。 In that case, on the service, when you recieve the BeginRun() call, execute the work on a non-WCF thread. 在这种情况下,在服务上,当您收到BeginRun()调用时,请在非WCF线程上执行工作。 This will free the channel & should allow you to immediately dispose the client. 这将释放频道并应允许您立即处置客户端。

Even though you've marked the OperationContract as IsOneWay , that doesn't mean WCF immediately releases the channel. 即使您将OperationContract标记为IsOneWay ,也不意味着WCF立即释放该通道。 A WCF service will not actually return from a one-way call until all of the data has been read from the wire. WCF服务实际上不会从单向调用中返回,直到从有线读取了所有数据为止。 Depending on your service configuration, this could involve waiting for previous calls to complete (particularly w/ Single concurrency mode sessionful service configurations). 根据您的服务配置,这可能涉及等待先前的调用完成(尤其是带有单并发模式的会话式服务配置)。

So, for several reasons it's often a good idea to actually execute service work on a separate thread from the WCF thread, which should improve throughput. 因此,出于多种原因,通常最好在与WCF线程不同的线程上实际执行服务工作,这将提高吞吐量。 Take a look at this article on MSDN for additional details. 有关其他详细信息,请参阅MSDN上的这篇文章

You can try the IChannel approach. 您可以尝试IChannel方法。 Or maybe try this, not sure this will work : http://msdn.microsoft.com/en-us/library/ms731177.aspx 或者,也许尝试此操作,不确定是否可以正常使用: http : //msdn.microsoft.com/zh-cn/library/ms731177.aspx

You need to add try catch block inside your code and if there is an timeout exception it should abort the client. 您需要在代码中添加try catch块,如果存在超时异常,它将中止客户端。

        try
        {
            work(client);
            client.Close();
        }

        catch (Exception e)
        {
            client.Abort();
            throw;
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM