Skip to content Skip to sidebar Skip to footer

How To Avoid Lags In A Uwp Tcp Client?

I'm trying to create a TCP client/server program between a python server (first PC) and an UWP client app (second PC). I want to simulate a fast python server that sends a message

Solution 1:

Your data is essentially a random output. There are many reasons could affect the output, such as the network delay, CPU usage. For example, if your network lag is 160ms, during these 160ms, your client can’t receive messages, but your update method is continued, which causes four update messages will appear continuously.

Therefore, I suggest you don’t separate these two tasks, you could do these in a Task. You could calculate the message numbers instead of using Task.Delay(40) to determine when to print the update message, in other words, you could print an update message every 40 messages

Solution 2:

As per Arya's answer, it's almost impossible to guarantee an exact interval between operations because of external factors. As I mentioned in the comments, you can however trigger the reading of the message at more or less regular intervals and avoid reading twice as follows (this is a Console NET Framework app; no need to completely change what you did, I just adapted for non UWP app):

publicclassProgram
{
    publicstaticvoidMain(string[] args)
    {
        StartTimer();
        StartClient();
        Console.ReadKey();
    }

    privatestaticstring message;
    privatestaticreadonly Stopwatch sw = new Stopwatch();
    privatestaticreadonlyobject lockobject = newobject();
    privatestatic Timer timer;

    privatestaticvoidStartClient()
    {
        conststring ip = "127.0.0.1";
        constint port = 4444;
        
        var tcpClient = new TcpClient();

        try
        {
            var ipep = new IPEndPoint(IPAddress.Parse(ip), port);
            tcpClient.Connect(ipep);

            Task.Run(() => {
                using (var networkStream = tcpClient.GetStream())
                using (var writer = new StreamWriter(networkStream))
                using (var reader = new StreamReader(networkStream, Encoding.UTF8))
                {
                    writer.WriteLine("Hello, World!");
                    writer.Flush();

                    sw.Start();

                    while (true)
                    {
                        try
                        {
                            // Add this lock for synchronization on message between the threads.lock (lockobject)
                            {
                                message = reader.ReadLine();
                                Console.WriteLine($"[Task]  Message: {message} at {sw.ElapsedMilliseconds}ms");
                            }
                        }
                        catch (Exception ex)
                        {
                            // Break the loop and stop timer in case of exception.
                            timer.Change(Timeout.Infinite, Timeout.Infinite);
                            Console.WriteLine(ex);
                            break;
                        }
                    }
                }
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            timer.Change(Timeout.Infinite, Timeout.Infinite);
        }
    }

    privatestaticvoidStartTimer()
    {
        // Replace the loop by a timer and lock on the read message operation.
        timer = new Timer(_ => 
            {
                lock (lockobject)
                {
                    Console.WriteLine($"[Timer] Message: {message} at { sw.ElapsedMilliseconds}ms");
                }
            }, 
            null, 0, 40);
    }
}

The output with this is as follows:

[Timer] Message:  at 0ms
[Task]  Message: 1 at 0ms
[Task]  Message: 2 at 18ms
[Task]  Message: 3 at 33ms
[Task]  Message: 4 at 49ms
[Task]  Message: 5 at 65ms
[Timer] Message: 5 at 66ms <- timer message
[Task]  Message: 6 at 81ms
[Task]  Message: 7 at 97ms
[Task]  Message: 8 at 112ms
[Timer] Message: 8 at 113ms <- timer message
[Task]  Message: 9 at 128ms
[Task]  Message: 10 at 144ms
[Task]  Message: 11 at 160ms
[Timer] Message: 11 at 161ms <- timer message
[Task]  Message: 12 at 176ms
[Task]  Message: 13 at 192ms
[Task]  Message: 14 at 207ms
[Timer] Message: 14 at 208ms
[Task]  Message: 15 at 223ms
[Task]  Message: 16 at 239ms
[Task]  Message: 17 at 255ms
[Timer] Message: 17 at 256ms
...

You get Timer (former Update) reads at regular intervals and no duplicates. If you need even more accurate intervals, it starts to become much more tricky (see this answer). Not sure this is required for your scenario though.

Post a Comment for "How To Avoid Lags In A Uwp Tcp Client?"