我想知道,我怎样才能证明DownloadStringTaskAsync方法是在同一线程中触发的,或者不是在Main方法中触发的。
class Program
{
static void Main(string[] args)
{
WebClient w = new WebClient();
Task<string> resultFromWebClient = w.DownloadStringTaskAsync("http://www.omdbapi.com/?s=batman");
Console.WriteLine($"result = {resultFromWebClient.Result}");
Console.ReadKey();
}
}发布于 2017-04-30 05:59:47
任务在哪个线程上运行由TaskScheduler决定(https://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler(v=vs.110).aspx。
因此,在大多数情况下,这是未定义的。这主要取决于线程池中有哪些线程可用。例如,如果没有可用的线程,任务将不得不等待分配到线程。
然而,在本例中,它肯定不会在同一个线程上运行,因为Main()方法永远不会将它的线程释放到线程池中,因为它不会等待任何东西。
要找出异步方法调用发生在哪个线程上,您可以编写代码:
Task<string> resultFromWebClient = w.DownloadStringTaskAsync("http://www.omdbapi.com/?s=batman");转换成它的等价形式:
Task<string> resultFromWebClient = Task.Run(async () =>
{
var myCurrentThreadIs = System.Threading.Thread.CurrentThread;
return await w.DownloadStringTaskAsync("http://www.omdbapi.com/?s=batman").ConfigureAwait(false);
}然而,DownloadStringTaskAsync()可以在多个线程上运行,因为它的内部代码可能会等待一些东西,然后将它的线程释放到线程池中,并且在恢复时会被分配一个不同的线程。上面的代码将确定它首先被分配给哪个线程。您可以使用ConfigureAwait(true)使其同步回其先前的上下文,但这不能保证将其同步回初始线程。这取决于特定的SynchronizationContext。
发布于 2017-04-30 06:09:36
如何证明DownloadStringTaskAsync方法是在同一线程中激发的,或者不是在Main方法中激发的。
那么,您可以启用网络跟踪并检查ETW日志中的线程id。
或者,您可以创建自己的async方法并进行测试:
static void Main(string[] args)
{
WebClient w = new WebClient();
Console.WriteLine(Environment.CurrentManagedThreadId);
Task<string> resultFromWebClient = GetAsync(w);
Console.WriteLine($"result = {resultFromWebClient.Result}");
Console.ReadKey();
}
static async Task<string> GetAsync(WebClient w)
{
Console.WriteLine(Environment.CurrentManagedThreadId);
return await w.DownloadStringTaskAsync("http://www.omdbapi.com/?s=batman");
}https://stackoverflow.com/questions/43700763
复制相似问题