C# 包装'HttpListener`'GetContextAsync()`
我试图包装HttpListener类,并添加更多处理Web套接字的逻辑 最后,我尝试包装GetContextAsync方法,以仅返回HttpListenerContext对象,这些对象是web套接字 到目前为止,我已经: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();
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
}
}