取消长时间运行的异步WCF呼叫到SSRS

时间:2016-02-07 12:07:14

标签: c# wcf task-parallel-library reportingservices-2005

我在后台线程上连接到SSRS 2005服务并调用Render方法

https://msdn.microsoft.com/en-us/library/reportexecution2005.reportexecutionservice.render.aspx

Render方法的代码很好,内置了取消令牌支持并按预期取消。

然而,Render方法WCF调用本身不支持取消令牌,在我的情况下此操作最多可能需要1-2个小时,如果有人决定取消,我不想长时间保持我的服务

有没有办法取消WCF调用'在飞行中',以便它可以抛出一个operationcancelledexception(或类似的东西),而不是保持我的客户端应用程序资源?

1 个答案:

答案 0 :(得分:3)

首先,您需要turn on asynchronous methods generation用于WCF客户端。您需要创建并await一项新任务,该任务将在SSRS操作完成或请求取消时结束。您可以使用How do I cancel non-cancelable async operations?文章中的WithCancellation扩展程序来实现此目的:

public static async Task<T> WithCancellation<T>( 
                                this Task<T> task, CancellationToken cancellationToken) 
{ 
    var tcs = new TaskCompletionSource<bool>(); 
    using(cancellationToken.Register( 
                s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs)) 
        if (task != await Task.WhenAny(task, tcs.Task)) 
            throw new OperationCanceledException(cancellationToken); 
    return await task; 
}

像这样使用:

// WithCancellation will throw OperationCanceledException if cancellation requested
RenderResponse taskRender = await ssrsClient.RenderAsync(renderRequest)
                                            .WithCancellation(cancellationToken);

renderRequest是生成的类RenderRequest的实例。

我不确定如何访问同步版out操作中出现的Render参数中的值,因为我目前无法访问SSRS。