C# 如何调试异步

C# 如何调试异步,c#,asp.net-core,C#,Asp.net Core,这个问题对我来说可能很简单,但我真的不知道怎么做 我创建了一个具有多个相互调用的方法的类(第一个方法执行一些逻辑,然后调用第二个方法,依此类推)。所有这些方法都是异步的,因为它们等待从外部服务器发布和获取方法 我想调试我的工作,看看它在每个阶段是如何工作的,我哪里出错了,但我不知道怎么做。我尝试直接从主函数调用第一个函数,并添加一个断点,但得到的结果是“wait”缺失,在addi之后 n“wait”我得到了使方法异步所需的收益,这与我的目的相矛盾 我能做什么 public static

这个问题对我来说可能很简单,但我真的不知道怎么做

我创建了一个具有多个相互调用的方法的类(第一个方法执行一些逻辑,然后调用第二个方法,依此类推)。所有这些方法都是异步的,因为它们等待从外部服务器发布和获取方法

我想调试我的工作,看看它在每个阶段是如何工作的,我哪里出错了,但我不知道怎么做。我尝试直接从主函数调用第一个函数,并添加一个断点,但得到的结果是“wait”缺失,在addi之后 n“wait”我得到了使方法异步所需的收益,这与我的目的相矛盾

我能做什么

    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
,我很难理解