C# 使用async/await和Task.Run时,不会显示特定的异常
我有一个网页,上面有食谱列表。在我的代码中,我循环浏览页面并下载每个食谱。下面是我正在做的工作的伪代码:C# 使用async/await和Task.Run时,不会显示特定的异常,c#,io,async-await,task,C#,Io,Async Await,Task,我有一个网页,上面有食谱列表。在我的代码中,我循环浏览页面并下载每个食谱。下面是我正在做的工作的伪代码: //This is the Recipe class //The constructor accepts a link to the recipe //This method scrapes the recipe public Task ScrapeAsync(){ return Task.Run(async () => { string WebPage;
//This is the Recipe class
//The constructor accepts a link to the recipe
//This method scrapes the recipe
public Task ScrapeAsync(){
return Task.Run(async () => {
string WebPage;
WebRequest request = WebRequest.Create(link);
request.Method = "GET";
using (WebResponse response = await request.GetResponseAsync())
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
WebPage = await reader.ReadToEndAsync();
}
//Non - async code here which is used to scrape the webpage
}
}
我使用Task.Run,因为方法中既有异步代码也有阻塞代码
//This is the RecipePage class
//This method scrapes the page
public Task GetRecipeListAsync(){
return Task.Run(async () => {
//I get the page using WebRequest and WebResponse in the same way as above
//Non - async/blocking code here which scrapes the page and finds links to recipes. I do await Recipe.ScrapeAsync() somewhere here.
//And I add the recipe objects to a public list in this class
}
}
在表单中,它循环浏览页面列表,并执行等待RecipePage.GetRecipeList()
和其他操作。下面是for循环的位置:
private async void go_Click(object sender, EventArgs e){
for (int i = (int)startingPageNUD.Value; i <= (int)finishingPageNUD.Value; ++i) {
RecipePage page = new RecipePage(page + i);
await page.GetRecipeListAsync();
//Some other code here
}
}
并告诉我发生了反射.TargetInvocationException
。它不会在我的代码中显示实际的异常。例如,如果我在代码中得到一个NullReferenceException
,它就不会显示它。
因此,我必须编写异步和非异步代码,并使用非异步代码进行调试。有什么办法解决这个问题吗?我还有一个问题。我是否以正确的方式使用async/await和Task?将getRecipeList代码封装在try/catch中 在catch代码中,获取异常消息和堆栈跟踪,并将它们分配给Recipe类的变量,当操作完成时,您将在主线程中测试/显示这些变量
private string TheException = "" ;
public Task GetRecipeListAsync()
{
TheException = "" ;
Task result = Task.Run(async () =>
{
try
{
//I get the page using WebRequest and WebResponse in the same way as above
...
}
catch (Exception Ex)
}
if (TheException!="") MessageBox.show(TheException) ;
// or Throw an exception with
return result ;
}
您也可以在GoClick程序中测试“异常”。好的。感谢你的编辑,我现在可以回答了 您的问题在于此函数:
private async void go_Click(object sender, EventArgs e){
for (int i = (int)startingPageNUD.Value; i <= (int)finishingPageNUD.Value; ++i) {
RecipePage page = new RecipePage(page + i);
await page.GetRecipeListAsync();
//Some other code here
}
}
private async void go\u单击(对象发送方,事件参数e){
对于(int i=(int)startingPageNUD.Value;i
我是否以正确的方式使用async/Wait和Task
非常接近。我认为没有必要执行任务。在这种情况下运行(它应该只用于将CPU密集型操作从UI线程中移出,而HTML抓取通常足够快,可以保留在UI上而不会产生任何不利影响)
另一个建议是让<代码>异步任务方法尽可能多地返回值,而不是将成员变量修改为副作用。在这种情况下,考虑使用<代码> SurasyNyc返回自己的列表,而不是更新共享列表,并使调用代码将列表合并。
关于您的异常,targetingException
将有一个包含详细信息的InnerException
。async void
事件处理程序中的异常与常规void
事件处理程序中的异常的管理方式几乎相同:如果有人转义了事件处理程序,那么它将转到应用程序主程序如果你不想要这个,你必须捕捉它(对于同步和异步处理程序).调用GetRecipeList
的代码是什么样子的?我已经编辑了这个问题。我知道如果抛出的异常无处可去,就会发生类似的异常。如果它是从返回void
而不是Task
的函数中的wait
抛出的,则可能会发生这种情况。如果您的配方加载循环在这样一个函数?不。循环只是在一个异步事件处理程序中。你能将该偶数处理程序的函数头添加到你的示例中吗?问题是:异常在哪里结束?每次等待都会重新抛出在等待的任务中抛出的异常。你能详细说明一下吗?我不太擅长抛出异常你在扔东西吗
private async void go_Click(object sender, EventArgs e){
for (int i = (int)startingPageNUD.Value; i <= (int)finishingPageNUD.Value; ++i) {
RecipePage page = new RecipePage(page + i);
await page.GetRecipeListAsync();
//Some other code here
}
}