-2

I'm currently learning C# and having an issue in running a method on a background thread before reassigning it to a new one (I have a socket that's working in the background that I need to close as I'm getting the Only one usage of each socket address (protocol/network address/port) is normally permitted exception). I set the tcpThread to null and thought it would kill everything inside it but I guess it the socket is still alive in heap.

This is to perform a restart TCP thread action if it hangs.

private static void startTCPServer()
{
    viewModel.stopTCPServer(); // I need to be able to call this on the existing tcpThread
    tcpThread = null;
    tcpThread = new Thread(new ThreadStart(viewModel.startTCPServer));
    tcpThread.Priority = ThreadPriority.AboveNormal;
    tcpThread.IsBackground = true;
    tcpThread.Start();
}

Also, is this the right approach?

EDIT: Here's using Task which results in the same issue:

    private static void startTCPServer()
    {
        tokenSource = new CancellationTokenSource();

        Task.Run(() =>
        {
            while (true)
            { 
                if (tokenSource.Token.IsCancellationRequested)
                {
                    viewModel.stopTCPServer();
                    break;
                } else
                {
                    viewModel.startTCPServer();
                    break;
                }
            }
        }, tokenSource.Token);
    }
Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
832049823
  • 91
  • 6
  • If you want to stop a thread you have to stop the thread. Threads can't stop each other, they can only stop themselves. So you have to somehow tell the thread to stop itself. – user253751 Jun 15 '22 at 13:54
  • 2
    Stop thinking in terms of threads. Try to work instead in terms of `Task`s, async and `CancellationToken`s. They more closely align with focussing on the *work to be done*, rather than on a specific *mechanism*, threads. – Damien_The_Unbeliever Jun 15 '22 at 13:58
  • Ok, if Tasks is the preferred way will the Task block the UI thread as this functionality is linked to a windows forms app? – 832049823 Jun 15 '22 at 14:03
  • Just done a quick rework using the code found here and I still get the same issue: https://stackoverflow.com/questions/51634383/how-to-stop-thread-in-c – 832049823 Jun 15 '22 at 14:12
  • _"I set the tcpThread to Null and thought it would kill everything inside it but I guess it the socket is still alive in heap."_ - there is not enough code here to tell what's actually the problem. The code shown doesn't make sense to me. The important parts are missing. Maybe consider creating a [mcve]. – Fildor Jun 15 '22 at 15:03

1 Answers1

0

You need cooperation from the background thread to shut it down correctly. The reasoning is explained in greater detail in What's wrong with using Thread.Abort(). A typical approach for this would be to use a cancellationToken to signal the background thread to shut down. In pseudo code

public void OnBackgroundThread();
  // create any resources in a using block at the start of the method
  while(!cts.Token.IsCancellationRequested){
    
     // Call some blocking method with a timeout
     RunBlockingOperation(timeout);
     // Better if the method accepts a cancellationToken
     RunBlockingOperation(cts.Token);
     // Or if there is an async, non blocking method
     // needs async keyword in method signature
     await RunAsyncOperation(cts.Token); 
  }

}

// Start thread
cts = new CancellationTokenSource();
task = Task.Factory.StartNew (OnBackgroundThread,TaskCreationOptions.LongRunning);

// Shut down thread
cts.Cancel();
// You need to await/wait for the background thread to complete
// Otherwise there is a risk that the resources are not released
// when the shutdown method has completed
await task; 

As mentioned in the comments, you should be using Tasks and not raw threads. This makes it a bit easier to synchronize the work.

However, if you are still learning c# you should spend some time studying thread safety. This is a rather large and complicated topic, but it is critical to know about the dangers whenever multiple threads are involved. Without this knowledge you will likely cause bugs that may be very difficult to find and reproduce.

If your goal is to simply make two computers communicate I would recommend using some higher level protocol/library than raw tcp. This way you will likely get a working solution much sooner with a reduced chance of causing bugs. There are plenty to choose from depending on your exact needs, see https://softwarerecs.stackexchange.com/

JonasH
  • 28,608
  • 2
  • 10
  • 23