以下之间有什么区别(如果有的话):
_listener = new HttpListener();
// Wait for an incoming request, then start a new task
// that executes ProcessContext()
var httpctx = await _listener.GetContextAsync();
await Task.Run(() => ProcessContext(httpctx));
/* -- or -- */
// Use ContinueWith to pass the incoming request to ProcessContext()
await _listener.GetContextAsync().ContinueWith(async (tsk) => {
if (tsk.Status != TaskStatus.RanToCompletion) Debug.Assert(false);
await ProcessContext(tsk.Result);
});
第一种方法需要一个尴尬的闭包来将上下文传递给新的Task,仅就这个事实而言,我倾向于认为第二种方法更好。我仍然是异步的新手,所以我可能是错的。
总体目标是让一个持续等待GetContextAsync结果的任务:
async Task Listen()
{
while (_listener != null && _listener.IsListening)
{
// Use one of the methods above to get the context
// and pass that context to a new task. This allows
// the current task to loop around and immediately
// resume listening for incoming requests
}
}
答案 0 :(得分:4)
第一个选项是使用Task.Run
将ProcessContext
卸载到ThreadPool
个帖子。第二种选择不会这样做。它只需完成GetContextAsync
并继续执行ProcessContext
。
但是,由于ContinueWith
不打算与async-await一起使用,它将同步运行,直到第一次等待,然后两者并行继续并将控制权返回给调用方法(所以不要混用{ {1}}和async-await)
目前还不清楚为什么这些是你的选择,因为你可以简单地调用这两种方法并等待结果:
ContinueWith
这与使用var httpctx = await _listener.GetContextAsync();
await ProcessContext(httpctx);
(正确使用时)非常相似,但显然更简单。在这里使用ContinueWith
并不是很有用。它主要用于并行代码或从UI线程卸载。