在 C# Cookbook 的第 18 页中,Stephen Cleary 定义了异步编程:“一种使用 futures 或回调来避免不必要的线程的并发形式。”但在代码中,所有异步方法都使用多线程(线程池)。请给我一个使用主线程而不阻塞主线程的异步方法的示例。
例如,考虑一个发送一些 http 请求并给你一些 http 响应的方法。如果此方法是同步的(例如 WebRequest.GetResponse()
),则 90% 的时间此方法将由于网络延迟而等待,因此执行此方法的线程将只是休眠而不执行任何操作。
当您使用异步方法(例如 HttpClient.PostAsync()
)并等待结果时,调用方法以第一个 await
结束,因此调用线程可以自由处理其他工作,也可以返回到 ThreadPool。收到您的 http 响应后,您的工作将恢复。
继续运行的线程取决于 SynchronizationContext
。因此,如果您从 UI 线程运行并等待 Async 方法,那么延续将在 UI 线程上运行。如果您从后台线程运行并等待一个异步方法,那么延续将在某个 ThreadPool 线程上运行。
async void button_click(object sender, EventArgs args)
{
_button.Enabled = false; // this is invoked on main thread
var response = await _httpClient.PostAsync(request);
// you will not block main thread and your UI will be responsive
// also you won't occupy ThreadPool thread for all the time to get the response
ProcessResponse(response); // this is invoked on main thread
}
一些 Async 方法只会在后台运行并在需要完成的所有时间内占用后台线程,而有些(基本上是 IO)不会。
我是一名优秀的程序员,十分优秀!