We had a strange issue at work – we had a misbehaving server, who worked perfectly well with one client but had strange issues when several clients connected to it. The server would broadcast a message to all of its clients but only one client would receive that specific message, re-sending the message would fix the problem occasionally but it wasn’t a very consistent behavior.
I’ve managed to find the root of the issue and created a simplified version of the issue. can you spot the bug in the following code?
public class Server
{
public void SendPingToClients(IEnumerable clients)
{
foreach (var client in clients)
{
Task.Factory.StartNew(() => Ping(client));
}
}
public void Ping(Client client)
{
Console.WriteLine("ping sent to client " + client.Id);
}
}
Happy coding!
Something ReSharper would've picked up – access to a modified closure. By the time the delegate (lambda) is executed, the “client” variable will not be the one passed into the lambda.
The lambda closed on the loop variable (i.e. client), asynchronously using it, even though it changes in this thread. The results depend on the timing between the threads, but could be anything between sending all to the first client, through sending all of them, and to sending only to the last one…
You're both right of course – when you know to look for it you should find it easily, a simple fix for an issue that you need to be aware of – or use Resharper 🙂
You're both right of course – when you know to look for it you should find it easily, a simple fix for an issue that you need to be aware of – or use Resharper 🙂
The lambda closed on the loop variable (i.e. client), asynchronously using it, even though it changes in this thread. The results depend on the timing between the threads, but could be anything between sending all to the first client, through sending all of them, and to sending only to the last one…