这是Simple Daily Trigger类,我从某个控制器调用此函数 - >(" DailyTrigger(int hour,int minute,int second = 0)")。 下次第一次使用(使用Task.delay)时出现错误
public class DailyTrigger
{
readonly TimeSpan triggerHour;
public DailyTrigger(int hour, int minute , int second = 0)
{
triggerHour = new TimeSpan(hour, minute, second);
InitiateAsync();
}
async void InitiateAsync()
{
while (true)
{
var triggerTime = DateTime.Today + triggerHour - DateTime.Now;
if (triggerTime < TimeSpan.Zero)
triggerTime = triggerTime.Add(new TimeSpan(0,2,0));
await Task.Delay(triggerTime);
OnTimeTriggered?.Invoke();
}
}
从控制器中调用
var trigger = new DailyTrigger(13,01);
trigger.OnTimeTriggered += () =>
{
var res = AanModel.GetById<Company_Priority>(prio_obj.id);
res.version = "5";
res.Create();
};
该错误
&#34;异步模块或处理程序在异步时完成 操作仍在等待&#34;
答案 0 :(得分:3)
这是异步编程的一个众所周知的问题。您最好通过 jonpreece 阅读Quick tip: Avoid ‘async void’等文章,了解其工作原理。
错误:
异步模块或处理程序在异步时完成 手术还在等待。
说明
是的,你有竞争条件。在它之前返回的方法 完成执行。在引擎盖下,框架没有创建 该方法的任务因为该方法不返回任务。 因此,在调用FirstOrDefaultAsync时,该方法不会暂停 执行并遇到错误。
解决方案:
要解决此问题,只需更改方法的返回类型即可 从void到Task。别担心,你实际上不必返回 任何事情,如果编译器知道不生成构建错误 没有退货声明。一个简单的解决方案,当你知道什么 问题是!
更新:
如果您仍想继续在构造函数中调用异步方法,那么最好通过 Stephen Cleary 阅读Async OOP 2: Constructors。
异步构造带来了一个有趣的问题。这将是 能够在构造函数中使用await是有用的,但这意味着 构造函数必须返回一个表示一个的Task 将来构建的价值,而不是构造的价值 值。这种概念很难融入其中 现有语言。
底线是不允许异步构造函数,所以让我们 探索一些替代方案。
如果你阅读得足够远,你会看到......
什么不该做
public sealed class MyClass
{
private MyData asyncData;
public MyClass()
{
InitializeAsync();
}
// BAD CODE!!
private async void InitializeAsync()
{
asyncData = await GetDataAsync();
}
}
更好地检查它,这是一个非常有趣的阅读。