dem*_*emo 14 c# lambda asynchronous timer async-await
我有异步回调,它被传递到Timer(来自System.Threading)构造函数:
private async Task HandleTimerCallback(object state)
{
if (timer == null) return;
if (asynTaskCallback != null)
{
await HandleAsyncTaskTimerCallback(state);
}
else
{
HandleSyncTimerCallback(state);
}
}
Run Code Online (Sandbox Code Playgroud)
和计时器:
timer = new Timer(async o => await HandleTimerCallback(o), state, CommonConstants.InfiniteTimespan,
CommonConstants.InfiniteTimespan);
Run Code Online (Sandbox Code Playgroud)
有没有办法o在lambda中省略那个参数?非同步的原因我可以将我handler作为委托传递
timer = new Timer(HandleTimerCallback, state, CommonConstants.InfiniteTimespan,
CommonConstants.InfiniteTimespan);
Run Code Online (Sandbox Code Playgroud)
Ste*_*ary 33
有没有办法在lambda中省略那个参数?
当然,只需将您的事件处理程序方法定义为async void:
private async void HandleTimerCallback(object state)
Run Code Online (Sandbox Code Playgroud)
Vla*_*scu 10
您可以使用包装方法,如 David Fowler在这里推荐的:
public class Pinger
{
private readonly Timer _timer;
private readonly HttpClient _client;
public Pinger(HttpClient client)
{
_client = client;
_timer = new Timer(Heartbeat, null, 1000, 1000);
}
public void Heartbeat(object state)
{
// Discard the result
_ = DoAsyncPing();
}
private async Task DoAsyncPing()
{
await _client.GetAsync("http://mybackend/api/ping");
}
}
Run Code Online (Sandbox Code Playgroud)
我只是想提一下,.NET 6 引入了一个名为PeriodicTimer“异步优先”的新计时器类,并且完全避免了回调。
https://learn.microsoft.com/en-us/dotnet/api/system.threading.periodictimer
用法一开始看起来有点奇怪(因为它是一个无限循环),但由于它是异步的,它不会阻止其他线程的执行:
public async Task DoStuffPeriodically()
{
var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
while (await timer.WaitForNextTickAsync())
{
//do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
它完全避免了回调,使用更简单的代码,是后台服务的完美候选者。
你基本上会得到一个“永无止境的任务”。
要启动任务,只需调用,例如_ = DoStuffPeriodically()使用丢弃运算符(但要try-catch在方法内添加,以便后台任务不会崩溃)或通过以下方式启动此任务Task.Run
Nick Chapsas 有一个很好的视频解释了用法:https://www.youtube.com/watch?v= J4JL4zR_l-0(包括如何使用 aCancellationToken中止计时器)。
| 归档时间: |
|
| 查看次数: |
6912 次 |
| 最近记录: |