-1

in my current application, I send a UDP message, and resend after a second if the packet is not acknowledged by the server. For now I am using a volatile bool as a flag for termination, in the main thread, when ACK is recieved, the flag is set to true, as confirmed by breakpoints, yet after this, during the "if(done) break;" in my other thread, the flag is still false.

   ThreadStart processTaskThread = delegate {
            send(text);
        };
        new Thread(processTaskThread).Start();  

 void send(string text)
    {
        while (true)
        {
            byte[] data = Encoding.ASCII.GetBytes(text);
            _socket.BeginSend(data, 0, data.Length, SocketFlags.None, (ar) =>
            {
                State so = (State)ar.AsyncState;
                int bytes = _socket.EndSend(ar);
                Console.WriteLine("SEND: {0}, {1}", bytes, text);
            }, state);
            Thread.Sleep(1000);
            if (kill) break;
        }
    }

Now here the flag gets set to true correctly as confirmed by breakpoint:

  private void Receive()
    {
        _socket.BeginReceiveFrom(state.buffer, 0, bufSize, SocketFlags.None, ref epFrom, recv = (ar) =>
        {
            State so = (State)ar.AsyncState;
            int bytes = _socket.EndReceiveFrom(ar, ref epFrom);
            _socket.BeginReceiveFrom(so.buffer, 0, bufSize, SocketFlags.None, ref epFrom, recv, so);
            try { 
            string Rec = Encoding.ASCII.GetString(so.buffer, 0, bytes);

            if (Rec.StartsWith("ACK:"))
            {
                kill = true;
                return;
            }

But back in the conditional in the thread loop it remains false. Any help appreciated.

Sam Smith
  • 1
  • 1
  • Please provide a [mcve] that illustrates the problem; something we can just throw in a single file and compile/run. – Phil M Dec 14 '18 at 21:04
  • 1
    "I send a UDP message, and resend after a second if the packet is not acknowledged by the server" - This sounds like you should be using TCP, not UDP. – Gabriel Luci Dec 14 '18 at 21:05

1 Answers1

0

I guess your kill var isn't static and volatile doesn't mean thread safe as you can read here.

Each thread has it's own stack. You need to make the kill variable static if you want to share it with multiple threads. Currently, when you change it's state from true to false, it is changed on the first threads stack and not reflected to the second thread.

You need to make it static and make sure that the assignment is thread safe. This can be achieved using the Interlocked class.

BTW, there is a problem with using Interlocked on boolean's as you can see here. The workaround is to create an integer, increment it and check if it's greater than zero.

Amir Popovich
  • 29,350
  • 9
  • 53
  • 99