Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass async Callback to Timer constructor

I have async callback, which is passed into Timer(from System.Threading) constructor :

private async Task HandleTimerCallback(object state)
{
    if (timer == null) return;

    if (asynTaskCallback != null)
    {
        await HandleAsyncTaskTimerCallback(state);
    }
    else
    {
        HandleSyncTimerCallback(state);
    }
}

And Timer :

timer = new Timer(async o => await HandleTimerCallback(o), state, CommonConstants.InfiniteTimespan,
            CommonConstants.InfiniteTimespan);

Is there any way to omit that o param in lambda? Cause for not-async I can just pass my handler as delegate

 timer = new Timer(HandleTimerCallback, state, CommonConstants.InfiniteTimespan,
            CommonConstants.InfiniteTimespan);
like image 601
demo Avatar asked Aug 12 '16 12:08

demo


2 Answers

Is there any way to omit that o param in lambda?

Sure, just define your event handler method as async void:

private async void HandleTimerCallback(object state)
like image 72
Stephen Cleary Avatar answered Nov 13 '22 16:11

Stephen Cleary


You could use a wrapper method, as recommended by David Fowler here:

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");
    }
}
like image 7
Vlad Iliescu Avatar answered Nov 13 '22 16:11

Vlad Iliescu