gpt4 book ai didi

c# - 异步/等待异常处理

转载 作者:太空宇宙 更新时间:2023-11-03 17:41:47 26 4
gpt4 key购买 nike

我的问题基于文章Best Practices in Asynchronous Programming

所以我有这个代码

    async static void AsyncVersion()
{
Stopwatch sw = Stopwatch.StartNew();
string url1 = "http://rsdn.ru";
string url2 = "http://gotdotnet.ru";
string url3 = "http://blogs.msdn.com";

var webRequest1 = WebRequest.Create(url1);
Console.WriteLine("Before webRequest1.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
...


所以这段代码会抛出异常,例如当我没有inet连接时。因此,当我遵循msdn的指导并将方法的签名更改为Task(而不是void)时,但是在此之后,它吞噬了所有异常,但是,它们不是由外部 catch块处理的。

整个代码如下

using System;
using System.Diagnostics;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication8
{
class Program
{
async static Task AsyncVersion()
{
Stopwatch sw = Stopwatch.StartNew();
string url1 = "http://rsdn.ru";
string url2 = "http://gotdotnet.ru";
string url3 = "http://blogs.msdn.com";

var webRequest1 = WebRequest.Create(url1);
Console.WriteLine("Before webRequest1.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);

var webResponse1 = await webRequest1.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url1,
webResponse1.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);

var webRequest2 = WebRequest.Create(url2);
Console.WriteLine("Before webRequest2.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);

var webResponse2 = await webRequest2.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url2,
webResponse2.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);

var webRequest3 = WebRequest.Create(url3);
Console.WriteLine("Before webRequest3.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
var webResponse3 = await webRequest3.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url3,
webResponse3.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);
}
static void Main(string[] args)
{

try
{
Console.WriteLine("Main thread id: {0}", Thread.CurrentThread.ManagedThreadId);
Task task = new Task(() => AsyncVersion());
task.Start();
Console.WriteLine("Right after AsyncVersion() method call");
//Ожидаем завершения асинхронной операции
task.Wait();
Console.WriteLine("Asyncronous task finished!");

}
catch (Exception e)
{
//Все исключения в TPL пробрасываются обернутые в AggregateException
Console.WriteLine("Exceptopn: {0}", e.Message);
}
Console.ReadLine();
}
}
}


旧版:

using System;
using System.Diagnostics;
using System.Net;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication8
{
class Program
{
async static void AsyncVersion()
{
Stopwatch sw = Stopwatch.StartNew();
string url1 = "http://rsdn.ru";
string url2 = "http://gotdotnet.ru";
string url3 = "http://blogs.msdn.com";

var webRequest1 = WebRequest.Create(url1);
Console.WriteLine("Before webRequest1.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);

var webResponse1 = await webRequest1.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url1,
webResponse1.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);

var webRequest2 = WebRequest.Create(url2);
Console.WriteLine("Before webRequest2.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);

var webResponse2 = await webRequest2.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url2,
webResponse2.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);

var webRequest3 = WebRequest.Create(url3);
Console.WriteLine("Before webRequest3.GetResponseAsync(). Thread Id: {0}",
Thread.CurrentThread.ManagedThreadId);
var webResponse3 = await webRequest3.GetResponseAsync();
Console.WriteLine("{0} : {1}, elapsed {2}ms. Thread Id: {3}", url3,
webResponse3.ContentLength, sw.ElapsedMilliseconds,
Thread.CurrentThread.ManagedThreadId);
}
static void Main(string[] args)
{

try
{
Console.WriteLine("Main thread id: {0}", Thread.CurrentThread.ManagedThreadId);
Task task = new Task(AsyncVersion);
task.Start();
Console.WriteLine("Right after AsyncVersion() method call");
//Ожидаем завершения асинхронной операции
task.Wait();
Console.WriteLine("Asyncronous task finished!");

}
catch (System.AggregateException e)
{
//Все исключения в TPL пробрасываются обернутые в AggregateException
Console.WriteLine("AggregateException: {0}", e.InnerException.Message);
}
Console.ReadLine();
}
}
}

最佳答案

new Task(() => AsyncVersion())


这是有问题的部分。 Task构造函数不理解 async,因此它将忽略从 Task返回的 AsyncVersion。 (您必须使用lambda而不是直接编写 AsyncVersion的事实应该已经使您警觉到正在发生奇怪的事情。)

您有几种解决方法(最后选择最好):


也将 Task<Task>Wait()用作内部 Task

Task<Task> task = new Task<Task>(AsyncVersion);
task.Start();
task.Result.Wait();

使用 Unwrap()Task<Task>更改为代表两个 TaskTask

Task<Task> task = new Task<Task>(AsyncVersion);
task.Start();
task.Unwrap().Wait();

使用 Task.Run(),它确实了解 async

Task task = Task.Run(() => AsyncVersion());
task.Wait();

根本不启动 Task,只需调用 async方法:

Task task = AsyncVersion();
task.Wait();

关于c# - 异步/等待异常处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18687580/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com