title: C# Aborting a thread: Thread abort is not supported on this platform
body: <h2>The Problem</h2>
  <p>I've created a thread in c# (<em><strong>on windows 10</strong></em>), which asks a server for some data:</p>
  <ul>
  <li>Such a thread should be created each time the user enters a certain menu (<code>mainMenuJoinRoomButtonClick()</code>)</li>
  <li>It should be closed each time the users exits that menu (we exit with <code>roomListBackButtonClick()</code>)</li>
  </ul>
  <p>This is done in order for us to <strong>save resources</strong> and <strong>prevent errors</strong> which occur if the thread isn't closed. (please see the code below)</p>
  <p>I tried using <code>threadName.Abort()</code> but it gives me the following error:</p>
  <pre><code>System.PlatformNotSupportedException: 'Thread abort is not supported on this platform.'
  </code></pre>
  <p>I also tried <code>threadName.Interrupt()</code> which produces this error (the error occurs in the line: <code>Thread.Sleep(3000);</code>):</p>
  <pre><code>System.Threading.ThreadInterruptedException: 'Thread was interrupted from a waiting state.'
  </code></pre>
  <p>What is the problem here and how can I close the thread?</p>
  <hr />
  <h2>Research Done</h2>
  <p>Looking around the internet has <a href="https://stackoverflow.com/questions/710070/timeout-pattern-how-bad-is-thread-abort-really">showed</a> there is no good way to abort a thread, is that so?</p>
  <p>I also found <a href="https://stackoverflow.com/questions/53465551/dotnet-core-equivalent-to-thread-abort">this</a> answer (first one) which uses <code>Thread.sleep()</code> but this doesn't seem like a real solution because it doesn't release the thread's resources, and I'm unsure how to implement this solution in my code.</p>
  <hr />
  <h2>The Code</h2>
  <pre><code>namespace TriviaClient
  {
      public partial class MainWindow : Window
      {
          public const int GET_ROOMS_REQUEST = 92;
  
          public Thread refreshRoomsListThread;
  
          public static NetworkStream clientStream;
  
          public MainWindow()
          {
              StartClient();
              InitializeComponent();
          }
  
          public void refreshRoomList()
          {
              while (true)
              {
                  this.Dispatcher.Invoke((Action)(() =&gt;
                  {
                      roomsListErrorBox.Text = &quot;&quot;;
                  }));
                  serializeAndSendMessage(GET_ROOMS_REQUEST, &quot;&quot;);
                  Dictionary&lt;string, object&gt; response = receiveAndDeserializeMessage();
  
                  if (response.ContainsKey(&quot;status&quot;) &amp;&amp; (string)response[&quot;status&quot;] == &quot;1&quot;)
                  {
                      this.Dispatcher.Invoke((Action)(() =&gt;
                      {
                          roomsList.Items.Clear();
                      }));
  
                      Dictionary&lt;int, string&gt; rooms = new Dictionary&lt;int, string&gt;();
  
                      JArray Jrooms = (JArray)response[&quot;rooms&quot;];
  
  
                      foreach (JArray room in Jrooms)
                      {
                          rooms.Add((int)room[0], (string)room[1]);
                      }
  
                      foreach (KeyValuePair&lt;int, string&gt; roomInDict in rooms)
                      {
                          this.Dispatcher.Invoke((Action)(() =&gt;
                          {
                              roomsList.Items.Add(new Label().Content = $&quot;{roomInDict.Key}: {roomInDict.Value}&quot;);
                          }));
                      }
  
                  }
                  else if (response.ContainsKey(&quot;message&quot;))
                  {
                      this.Dispatcher.Invoke((Action)(() =&gt;
                      {
                          roomsListErrorBox.Text = (string)response[&quot;message&quot;];
                      }));
                  }
                  Thread.Sleep(3000);
              }
          }
          private void roomListBackButtonClick(object sender, RoutedEventArgs e)
          {
              refreshRoomsListThread.Abort();
  
          }
          private void mainMenuJoinRoomButtonClick(object sender, RoutedEventArgs e)
          {
              roomsListErrorBox.Text = &quot;&quot;;
  
              refreshRoomsListThread = new Thread(refreshRoomList);
              refreshRoomsListThread.Start();
  
          }
      }
  }
  
  </code></pre>