C# 包装'HttpListener`'GetContextAsync()`

C# 包装'HttpListener`'GetContextAsync()`,c#,asynchronous,async-await,task,C#,Asynchronous,Async Await,Task,我试图包装HttpListener类,并添加更多处理Web套接字的逻辑 最后,我尝试包装GetContextAsync方法,以仅返回HttpListenerContext对象,这些对象是web套接字 到目前为止,我已经: public Task<HttpListenerContext> GetContextAsync() { Task<HttpListenerContext> contextTask = listener.GetContextAsync();

我试图包装HttpListener类,并添加更多处理Web套接字的逻辑

最后,我尝试包装GetContextAsync方法,以仅返回HttpListenerContext对象,这些对象是web套接字

到目前为止,我已经:

public Task<HttpListenerContext> GetContextAsync()
{
    Task<HttpListenerContext> contextTask = listener.GetContextAsync();
    if (contextTask.Result.Request.IsWebSocketRequest)
    {
        return contextTask;
    }
    else
    {
        contextTask.Result.Response.StatusCode = 500;
        contextTask.Result.Response.Close();
        return GetContextAsync();
    }
}
在实现第一个连接之前,等待不会返回到主线程

编辑 如果这对某人有帮助,我最终会选择以下方式:

public async Task<HttpListenerContext> GetContextAsync()
{
    HttpListenerContext listenerContext = await listener.GetContextAsync();
    while (!listenerContext.Request.IsWebSocketRequest)
    {
        listenerContext.Response.StatusCode = 500;
        listenerContext.Response.Close();
        listenerContext = await listener.GetContextAsync();
    }
    return listenerContext;
}

如果您仔细观察您的方法:

public Task<HttpListenerContext> GetContextAsync()
{
    Task<HttpListenerContext> contextTask = listener.GetContextAsync();
    if (contextTask.Result.Request.IsWebSocketRequest)
您正在使contextTask阻塞线程,直到它使用Result获得一些响应:

访问属性的get访问器会阻塞调用线程,直到异步操作完成;这相当于调用Wait方法

基本上,你需要这样的东西:

public async Task<HttpListenerContext> GetContextAsync()
{
    HttpListenerContext context = await listener.GetContextAsync();
    if (context.Request.IsWebSocketRequest)
    {
        return context;
    }
    else
    {
        context.Response.StatusCode = 500;
        context.Response.Close();
        return await GetContextAsync(); //not sure here
    }
}

那你以为会发生什么?当您等待一个任务时,在任务完成之前,执行不会返回到等待点……我希望在等待任务完成时,主线程将继续。Wait不是这样做的吗?不,它不是,Wait释放TaskScheduler使用的线程,这并不意味着执行将继续。如果您不想等待任务执行结束,那么不要等待调用。另外,当您使用任务的Result属性时,它将阻塞线程。因此,您不能等待调用而不使用Result属性,将函数转换为async,在函数内部等待listener.GetContextAsync并使用结果,这样它就不会阻塞。我编辑了我的答案以反映@gusman所说的
public async Task<HttpListenerContext> GetContextAsync()
{
    HttpListenerContext context = await listener.GetContextAsync();
    if (context.Request.IsWebSocketRequest)
    {
        return context;
    }
    else
    {
        context.Response.StatusCode = 500;
        context.Response.Close();
        return await GetContextAsync(); //not sure here
    }
}