HttpContext 与 HttpListenerContext AcceptWebSocketRequest 无法转换覆盖的异步函数

HttpContext vs. HttpListenerContext AcceptWebSocketRequest unable to cast overridden async func

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

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 一切正常,但我宁愿不必保留 HttpContextBaseHttpContextWrapper 在我的项目中。

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

private async Task ProcessRequestAsync(HttpContextBase context)
{
    if (context.IsWebSocketRequest)
        await context.AcceptWebSocketRequest(HandleWebsocketRequest);
...

private async Task HandleWebsocketRequest(WebSocketContext context)
{
    ...

如果你想将 Func<WebSocketContext, Task> 传递给 Func<AspNetWebSocketContext, Task> 参数然后将其转换回 Func<WebSocketContext, Task> 以便你可以传递 HttpListenerWebSocketContext 你需要特别说明创建委托时键入。

如果您让编译器推断它将创建一个无法接受 HttpListenerWebSocketContext.

Func<AspNetWebSocketContext, Task> 委托

所以代替:

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> 而不是 Func<AspNetWebSocketContext, Task> 作为参数。