user584018
user584018

Reputation: 11304

how to get rid of the warning "captured variable is disposed in the outer scope"

For below code I am getting warning for client saying captured variable is disposed in the outer scope, what's is meaning for this and how can I get rid of it?

enter image description here

using (var client = DeviceClient.CreateFromConnectionString(""))
            {
                //Loop through each batch in the chunked list
                var concurrentTasks = list.Select(r=>
                    Task.Run(async () =>
                    {
                        await Push(r, client);

                    })).ToList();
                //complete all the tasks.
                await Task.WhenAll(concurrentTasks);
            }


 private async Task Push(List<R> r, DeviceClient client)
    {
      await client.SendEventAsync(new Message(e));
}

Upvotes: 2

Views: 3080

Answers (2)

JHBonarius
JHBonarius

Reputation: 11271

In this specific case it is clear that the warning is a false positive. Because the execution of all the Tasks is awaited at WhenAll the client will not be disposed early. You could locally disable the warning as described here.

HOWEVER, in this case there is another issue. By calling the Task.Run for just a simple async method call, you're wrapping the inner Task in another Task. That's not necessary and a bit of a waste. Especially since you're not in a synchronous scope, you could just write

await Task.WhenAll(
    list.Select(r => Push(r, client)).ToList());

Upvotes: 3

Stefan
Stefan

Reputation: 17658

client is being used as parameter inside the task, but disposed outside the task.

Effectively this could mean its disposure is not aligned with its usage causing potential nasty time based exceptions, due to the fact possibly multiple threads are involved.

Since you're awaiting all calls you should be safe, but if you use a nested method inside which doesn't, you run into this issue again.

The compiler is warning against this pattern.

To resolve you should create and dispose the client within the task or disable and ignore the warning.

@Johns addition to assign the variable to a task local variabele might also get rid of the warning, but keep in mind that does not resolve the potential issue, which in your case is unlikely to happen.

Upvotes: 1

Related Questions