C# Main中的异步方法立即返回
在NetCore2.2应用程序中,我使用c#level 7.3实现了以下主要功能C# Main中的异步方法立即返回,c#,.net-core,async-await,C#,.net Core,Async Await,在NetCore2.2应用程序中,我使用c#level 7.3实现了以下主要功能 public static async Task Main(string[] args) { _logger.TraceMethodBegins(nameof(Main)); AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; TaskSche
public static async Task Main(string[] args)
{
_logger.TraceMethodBegins(nameof(Main));
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
using (ServiceFactory.Instance)
{
try
{
Parser.Default.ParseArguments<Options>(args)
.WithParsed(async o =>
{
IWtgValuesCalculator wtgValuesCalculator = ServiceFactory.Instance.Kernel.Get<IWtgValuesCalculator>();
await wtgValuesCalculator.Calculate(o.StartDate, o.EndDate, o.FacilityName);
})
.WithNotParsed(async o =>
{
//Code enters over here
IWtgValuesCalculator wtgValuesCalculator = ServiceFactory.Instance.Kernel.Get<IWtgValuesCalculator>();
await wtgValuesCalculator.Calculate(null, null, null);
});
}
catch (Exception e)
{
_logger.Fatal(e, e.Message);
}
}
//And jump here immediately without awaiting
_logger.TraceMethodEnds(nameof(Main));
}
公共静态异步任务主(字符串[]args)
{
_TraceMethodBegins(name of(Main));
AppDomain.CurrentDomain.UnhandledException+=CurrentDomainOnUnhandledException;
TaskScheduler.UnobservedTaskeException+=TaskScheduleRonUnobservedTaskeException;
使用(ServiceFactory.Instance)
{
尝试
{
Parser.Default.ParseArguments(args)
.WithParsed(异步o=>
{
IWtgValuesCalculator wtgValuesCalculator=ServiceFactory.Instance.Kernel.Get();
等待wtgValuesCalculator.Calculate(o.StartDate、o.EndDate、o.FacilityName);
})
.WithNotParsed(异步o=>
{
//代码在这里输入
IWtgValuesCalculator wtgValuesCalculator=ServiceFactory.Instance.Kernel.Get();
等待wtgValuesCalculator.Calculate(null,null,null);
});
}
捕获(例外e)
{
_记录器。致命(e,e.Message);
}
}
//马上跳到这里,不用等待
_logger.TraceMethodds(名称(主要));
}
该方法立即返回,而不等待wait wtgValuesCalculator.Calculate()
我已验证没有异常,如果我将其更改为使用所有同步方法,程序将按预期运行。另外,调用wtgValueScalCalculator.Calculate(o.StartDate,o.EndDate,o.FacilityName).getWaiter().GetResult()代码>使其正确运行。一位同事告诉我,他在某个地方读到,Main中的异步方法可能有问题,因为mscorlib没有完全加载,但我找不到任何关于它的信息。谁能给我们带来一些线索?
亲切的问候 您在传递给WithParsed
和WithNotParsed
的异步方法中等待。您不必在async Main
方法中的任何地方等待
解析参数,然后等待wtgValuesCalculator。在Main中计算
换句话说:此时,您将两个异步方法发送到WithParsed/WithNotParsed,并在不等待Main的情况下继续。您的wait
仅在WithParsed/WithNotParsed委托的上下文中使用。每当出现wait时,您的方法将被分为2个部分:等待前和等待后(不是100%准确,但足够接近)。“第二个”方法将在等待的操作完成后执行,“第一个”部分将在等待的操作返回等待的操作时返回。
要使整个方法调用链等待“第二”部分,您需要对调用树上的每个可等待的方法进行等待。如果这是为使用async
而构建的,那么链在ParseArguments
之后返回的任何内容都是可等待的。如果是这样的话,你会得到警告的。您的lambda几乎可以肯定正在有效地转换为某种异步void
,因此无法判断它们何时完成。看起来您正在命中,这会调用您的委托,而不关心它是否是等待
可能。@KirkLarkin有趣。。因此,如果我下载源代码并创建一个异步实现,我可以期望它能正常工作?理论上,是的,但与其派生一个现有的开源库,不如直接获取ParseArguments的结果并使用它,而不是使用WithParsed和WithNotParsed?