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?
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));
}
CodePudding user response:
I think the inner code is wrong anyhow. You're not in a synchronous scope, so just write
await Task.WhenAll(
list.Select(r => Push(r, client)).ToList());
No need for all the separate Task.Run
s because they just wrap a Task in Task
CodePudding user response:
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.