我有一个异步函数(不会返回实际值,只返回Task对象),我需要在类构造函数中运行,以及当Threading.Timers.Timer触发时。
我无法将构造函数sub标记为async,当我使用AddressOf设置计时器回调时,它会警告我"从此异步函数返回的任务将被删除,并且忽略其中的任何异常。考虑将其更改为Async Sub,以便传播其异常。"。我听说使用Async subs / void不是一个好主意,如果可能的话应该避免使用。
构造函数代码
Public Sub New(File As String)
Me.New()
Await ImportXml(File)
End Sub
定时器代码
Private WithEvents SaveTimer As New Threading.Timer(AddressOf Save, Nothing, 30 * 1000, Threading.Timeout.Infinite)
我认为使用构造函数我可以将文件的加载分成单独的子文件(除非有更好的方法),但不知道如何处理计时器。我想知道我是否做错了,并且有办法安排任务,某种任务计时器?
答案 0 :(得分:5)
由于构造函数无法返回任务,您可以改为使类型隐藏其构造函数并公开 异步的一个或多个工厂方法,并返回该类型的用户可用于创建实例的任务: / p>
public class Foo
{
private Foo()
{
}
public static async Task<Foo> CreateAsync()
{
Foo foo = new Foo();
await foo.InitializeAsync();
return foo;
}
}
对于计时器,你可以简单地避免使用实际的计时器,只需创建一个async
方法:
public static async Task DoStuff()
{
while (true)
{
await Task.Run(() => SomeWork());
await Task.Delay(TimeSpan.FromSeconds(30));
}
}
答案 1 :(得分:1)
你不能await
构造函数中的任务(这是正确的,因为你不能从构造函数返回任务)。但是,您可以在构造函数中启动任务,将其作为属性存储在类中,并在实际需要时将其存储为await
:
public class Hamster
{
public Task Creation { get; private set; }
public Hamster()
{
Creation = CreateAsync();
}
}
var hamster = new Hamster();
await hamster.Creation;
...并且有一种方法来安排任务,某种任务计时器
是的,有。您可以启动任务,并使用Task.Delay
async Task DoSomethingAsync(CancellationToken cancellationToken)
{
await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken);
DoSomething();
}