hikalkan / scs

TCP Server/Client Communication and RMI Framework
MIT License
225 stars 112 forks source link

concurrency problem #5

Open MithrilMan opened 10 years ago

MithrilMan commented 10 years ago

well done! I'm just reporting some errors about multithread clients

I'm taking Chat Server as an example take this function as example:

/// <summary>
/// Sends a public message to room.
/// It will be seen all users in room.
/// </summary>
/// <param name="message">Message to be sent</param>
public void SendMessageToRoom(ChatMessage message)
{
    //Get ChatClient object
    var senderClient = _clients[CurrentClient.ClientId];
    if (senderClient == null)
    {
        throw new ApplicationException("Can not send message before login.");
    }

    //Send message to all online users
    Task.Factory.StartNew(
        () =>
        {
            foreach (var chatClient in _clients.GetAllItems())
            {
                try
                {
                    chatClient.ClientProxy.OnMessageToRoom(senderClient.User.Nick, message);
                }
                catch
                {

                }
            }
        });
}

here you call a task that, in the same thread, try to call

chatClient.ClientProxy.OnMessageToRoom(senderClient.User.Nick, message);

this cause that if a client has problems completing the response, stuck all the queue I've experienced it just launching 2 chat clients and debugging one of them, setting up a breakpoint in the

OnMessageToRoom
client function then sending a message from the other client to the room

while the debugged instance hit the breakpoint, the other client didn't received its sent message and couldn't sent others. as soon as i resumed the paused debugged client, all messages arrived.

I tried to create an inner Task instead of an outer:

foreach (var chatClient in _clients.GetAllItems()) {
               try {
                  //Send message to all online users
                  Task.Factory.StartNew(() => {
                     chatClient.ClientProxy.OnMessageToRoom(chatRoom, message);
                  });
               }
               catch {
               }
            }
inside the foreach loop but that helped only partially: i was able to receive first message sent, but then i couldn't send another (interface freeze, so i suppose the server didn't was in some lock state, didn't accepting a new message until the previous one ended to be dispatched can you explain how to solve this problem and suggest how to fix that? thanks and again, good job on this library!
MithrilMan commented 9 years ago

any news ?