HttpContext与HttpListenerContext AcceptWebSocketRequest无法转换重写的异步函数

时间:2015-03-07 07:28:08

标签: c# .net casting async-await

我正在尝试使用HttpContextBaseHttpListenerHttpHandler之间共享代码。 HttpContextWrapper已经提供,但我必须自己创建HttpListenerContextWrapper,这很容易,直到我AcceptWebSocketRequest。问题是HttpContextBase.AcceptWebSocketRequest中的回调是键入Func<AspNetWebSocketContext, Task>而不是Func<WebSocketContext, Task>,我正在努力将其转换为派生类。

public class HttpListenerContextWrapper : HttpContextBase
{
    private HttpListenerContext _context;

    public HttpListenerContextWrapper(HttpListenerContext context)
    {
        _context = context;
    }

    public override async void AcceptWebSocketRequest(Func<AspNetWebSocketContext, Task> callback)
    {
        // can't implicitly convert HttpListenerWebSocketContext to AspNetWebSocketContext..
        await callback(await _context.AcceptWebSocketAsync(null));

        // throws at runtime..
        await callback((AspNetWebSocketContext)(WebSocketContext)await _context.AcceptWebSocketAsync(null));

        // throws at runtime..
        await ((Func<WebSocketContext, Task>)callback)(await _context.AcceptWebSocketAsync(null));

        // throws at runtime..
        await ((Func<HttpListenerWebSocketContext, Task>)callback)(await _context.AcceptWebSocketAsync(null))
    }

    // no suitable method found to override..
    public override async void AcceptWebSocketRequest(Func<WebSocketContext, Task> callback)
    {

运行时异常始终为:Unable to cast object of type Func<AspNetWebSocketContext,Task> to type Func<WebSocketContext,Task> ..at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__4

调用AcceptWebSocketRequest的代码已键入WebSocketContext,并且在直接使用HttpContextHttpListenerContext时效果很好。有没有办法创建兼容的回调?或者是否有更好的方式来抽象HttpContextHttpListenerContext

如果我复制HttpContextBase的代码并将类型更改为WebSocketContext一切正常,但我不想保留HttpContextBase和{{1}的屠宰副本在我的项目中。

编辑:这是使用该方法的代码。

HttpContextWrapper

1 个答案:

答案 0 :(得分:1)

如果您想将Func<WebSocketContext, Task>传递给Func<AspNetWebSocketContext, Task>参数,然后将其转发回Func<WebSocketContext, Task>,那么您可以传入HttpListenerWebSocketContext,您需要明确说明该类型你创建了委托。

如果您让编译器推断它将创建一个无法接受Func<AspNetWebSocketContext, Task>的{​​{1}}委托。

所以而不是:

HttpListenerWebSocketContext

你需要:

await context.AcceptWebSocketRequest(HandleWebsocketRequest);

Func<WebSocketContext, Task> action = HandleWebsocketRequest; await context.AcceptWebSocketRequest(action); 中你需要把它丢回来:

AcceptWebSocketRequest

然而,由于await ((Func<WebSocketContext, Task>)callback)(await _context.AcceptWebSocketAsync(null)); 参数的类型为callback,因此非常危险且设计不佳,并且您无法保证所有来电者都会发送Func<AspNetWebSocketContext, Task>而不是Func<WebSocketContext, Task>作为论据。