What is the best way for ensuring a C# async Task is returned when calling a function two times?

StackOverflow https://stackoverflow.com/questions/22955943

Pregunta

I have the following code snipped which fails.

public class Service
{
    private int _called = 0;

    public Task<int> DoAsync()
    {
        return Task.Run(() => Do());
    }

    private int Do()
    {
        System.Threading.Thread.Sleep(200); // fake business.
        return ++_called;
    }
}

public class AsyncTaskTests
{
    [Test]
    public async Task When_calling_async_function_twice_then_first_task_should_be_returned()
    {
        var sut = new Service();
        var t1 = sut.DoAsync();
        var t2 = sut.DoAsync();
        await Task.WhenAll(t1, t2);
        Assert.That(t1.Result, Is.EqualTo(1));
        Assert.That(t2.Result, Is.EqualTo(1));
    }
}

How can I ensure that the result of t1 and t2 is the same? Is there something I need to consider additionally?

¿Fue útil?

Solución

You can adjust your service class like this for getting the expected behaviour.

public class Service
{
    private int _called = 0;
    private Task<int> _asyncTask;

    public Task<int> DoAsync()
    {
        if (!IsFinished)
            return _asyncTask;

        _asyncTask = Task.Run(() => Do());
        return _asyncTask;
    }

    private bool IsFinished
    {
        get
        {
            return _asyncTask == null ||
                   _asyncTask.IsCompleted ||
                   _asyncTask.IsCanceled ||
                   _asyncTask.IsFaulted;
        }
    }

    private int Do()
    {
        System.Threading.Thread.Sleep(200); // fake business.
        return ++_called;
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top