Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Cannot convert void to Task, when passing a delegate to a method with generic

I have the following method that accepts a delegate:

public async Task<T> ExecuteWithRetryAsync<T>(Func<Task<T>> action)
        {
            try
            {
                return await _retryPolicy.ExecuteAsync(async () =>
                {
                    return await action();
                });
            }
            catch (HttpRequestException)
            {
                return default(T);
                //log this to queue
            }
        }

Normally I call it this way and it works fine:

  var saleCheckResult = await ExecuteWithRetryAsync(async () => await _client.CheckSaleAsync(SaleId));

This is the delegate I am passing:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  public virtual System.Threading.Tasks.Task<SaleCheckResult> CheckSaleAsync(string saleId)
    {
        return CheckSaleAsync(saleId, System.Threading.CancellationToken.None);
    }

Here is the problem, I have the following method I want to pass to the Execute with retry as a delegate:

 public virtual System.Threading.Tasks.Task DisableMachineAsync(string machineId)
    {
        return DisableMachineAsync(machineId, System.Threading.CancellationToken.None);
    }

I am using the same logic to call it:

await ExecuteWithRetryAsync(async () => await _client.DisableMachineAsync(machineId));

I get the following error " type arguments for method cannot be inferred from usage try to specify arguments explicitly", I understand I should specify arguments, so I tried this since the delegate returns a Task

  await ExecuteWithRetryAsync<Task>(async () => await _client.DisableMachineAsync(machineId))

Now I get an error cannot implicitly convert void to Task, something I dont understand I cannot use void as a type argument so how can I make sure I pass the correct delegate. Why is it telling me that it wants to convert void to Task, the delegate is returning Task and also the ExecuteWithRetry, how can I make this compile. I found a similar post here but thats a bit different issue Cannot implicitly convert type 'void' to 'System.Threading.Tasks.Task'

>Solution :

You can create an overload which will accept Func<Task>:

async Task ExecuteWithRetryAsync(Func<Task> action)
{
    try
    {
        await _retryPolicy.ExecuteAsync(async () =>
        {
             await action();
        });
    }
    catch (HttpRequestException)
    {
        //log this to queue
    }
}

And let compiler select an overload based on the provided func.

Why is it telling me that it wants to convert void to Task

Because this invocation await ExecuteWithRetryAsync<Task> requires return type of Task<Task>, while awaiting Task results in void.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading