C# 如何调试异步
这个问题对我来说可能很简单,但我真的不知道怎么做 我创建了一个具有多个相互调用的方法的类(第一个方法执行一些逻辑,然后调用第二个方法,依此类推)。所有这些方法都是异步的,因为它们等待从外部服务器发布和获取方法 我想调试我的工作,看看它在每个阶段是如何工作的,我哪里出错了,但我不知道怎么做。我尝试直接从主函数调用第一个函数,并添加一个断点,但得到的结果是“wait”缺失,在addi之后 n“wait”我得到了使方法异步所需的收益,这与我的目的相矛盾 我能做什么C# 如何调试异步,c#,asp.net-core,C#,Asp.net Core,这个问题对我来说可能很简单,但我真的不知道怎么做 我创建了一个具有多个相互调用的方法的类(第一个方法执行一些逻辑,然后调用第二个方法,依此类推)。所有这些方法都是异步的,因为它们等待从外部服务器发布和获取方法 我想调试我的工作,看看它在每个阶段是如何工作的,我哪里出错了,但我不知道怎么做。我尝试直接从主函数调用第一个函数,并添加一个断点,但得到的结果是“wait”缺失,在addi之后 n“wait”我得到了使方法异步所需的收益,这与我的目的相矛盾 我能做什么 public static
public static void Main(string[] args)
{
await LoadCampaignTempleteJSONAsync();
}
我只想遵循loadActivityTempleteJSonasync的过程,请尝试以下操作
class Program
{
static void Main(string[] args)
{
var p = new Program();
p.Run();
}
private async void Run()
{
await LoadCampaignTempleteJSONAsync();
}
private static Task LoadCampaignTempleteJSONAsync()
{
//Put breakpoint here!
throw new NotImplementedException();
}
}
并在LoadActivityTempleteJSonasync()中放置一个断点
这将到达断点请尝试以下操作
class Program
{
static void Main(string[] args)
{
var p = new Program();
p.Run();
}
private async void Run()
{
await LoadCampaignTempleteJSONAsync();
}
private static Task LoadCampaignTempleteJSONAsync()
{
//Put breakpoint here!
throw new NotImplementedException();
}
}
并在LoadActivityTempleteJSonasync()中放置一个断点
这将到达断点从Main调用异步方法的最简单方法是调用Result
或GetAwaiter()。GetResult()
:
此外,从C#7.1开始,您可以使Main异步:
public static async Task Main(string[] args)
{
await LoadCampaignTempleteJSONAsync();
}
从Main调用异步方法的最简单方法是调用Result
或GetAwaiter().GetResult()
:
此外,从C#7.1开始,您可以使Main异步:
public static async Task Main(string[] args)
{
await LoadCampaignTempleteJSONAsync();
}
如果你想等待,你需要让你的LoadCampaignTempleteJSONAsync()
返回任务或任务。你需要使你的主任务异步,否则你不能在其中调用等待。我只想调试它。而且它已经返回了一个任务。@jordyvaneijk您需要更具体地说明要调试的内容。如果在LoadCampaignTempleteJSONAsync
中放置断点,您将命中它。如果在调试模式下运行,只需将断点放在异步函数的后面/内部。你不能通过一次一行的方式从外部函数命中它。但是如果您在异步之前中断,并且在异步内部有另一个断点,并点击continue。它将命中另一个断点。@Yossi-你刚才删除了你的新问题,是因为catch(Exception ex)
是罪魁祸首吗?你需要让你的LoadCampaignTempleteJSONAsync()
如果要等待,请返回Task或Task。您需要使主任务异步,否则无法在其中调用Wait。我只想调试它。而且它已经返回了一个任务。@jordyvaneijk您需要更具体地说明要调试的内容。如果在LoadCampaignTempleteJSONAsync
中放置断点,您将命中它。如果在调试模式下运行,只需将断点放在异步函数的后面/内部。你不能通过一次一行的方式从外部函数命中它。但是如果您在异步之前中断,并且在异步内部有另一个断点,并点击continue。它将命中另一个断点。@Yossi-您是否因为catch(Exception ex)
是罪魁祸首而删除了新问题?如果程序在命中断点之前终止,则不会<如果LoadCampaignTemplete…
返回的任务
未完成,则会立即返回code>Run
,因此Main
将返回,并且进程将终止…,供以后阅读此内容的任何人使用。这不是一个好答案。@RenéVogt是对的,如果运行完成,它将不再到达断点。但是如果你做更多的工作,它可能会到达断点。或者,您可以在继续之前等待结果。如果程序在到达断点之前终止,则不能<如果LoadCampaignTemplete…
返回的任务
未完成,则会立即返回code>Run
,因此Main
将返回,并且进程将终止…,供以后阅读此内容的任何人使用。这不是一个好答案。@RenéVogt是对的,如果运行完成,它将不再到达断点。但是如果你做更多的工作,它可能会到达断点。或者,您可以在继续之前等待结果。注意:始终使用GetAwaiter().GetResult()
。仅使用Result
将导致死锁。另外,async Main
只是语法上的糖分。在后台,编译器只需定义一个常规的Main
,然后使用GetAwaiter().GetResult()
@ChrisPratt调用您的async Main
,我很难理解它为什么会死锁。首先,这是一个控制台应用程序。控制台应用程序没有SynchronizationContext,因此从等待的任务返回时没有真正的死锁方式。其次,Result
在实现上几乎与GetAwaiter().GetResult()
相同。唯一的区别是,Result
将每个异常都包装在aggregateeexception
中,这在调试时很烦人。告诉人们在某些情况下使用Result
是安全的,而在其他情况下则不然,这会导致灾难,因为他们总是可以使用GetAwaiter().GetResult()
,并且一直都很好。然后,您总会得到适当的异常作为奖励。@ChrisPratt关键是GetAwaiter().GetResult()
将死锁。使用异步方法创建WPF应用程序async Task doworksync(){await Task.Delay(5);返回1;}
,然后尝试与doworksync().GetAwaiter().GetResult()同步等待它代码>。这将是你一生中最长的5毫秒;在控制台应用程序中工作,但它是否适用于多个调用或Web应用程序?注意:始终使用GetAwaiter().GetResult()
。仅使用Result
将导致死锁。另外,async Main
只是语法上的糖分。在后台,编译器只需定义一个常规的Main
,然后使用GetAwaiter().GetResult()
@ChrisPratt调用您的async Main
,我很难理解