-1

I have one button and when I click on it, I am creating one thread and after 10 seconds I am aborting it. When I click on the button again it creates new thread, but the issue is when I use AWAIT, the thread is not aborted. Application is showing old thread's value with newly created thread. But when I am not using AWAIT, it's working fine. Below is just example of my Code.

Logic with AWAIT (you can see in the below image that old thread is also running) Click for View Image

try
        {
            var _Thread1 = new Thread(async () =>
            {
                int i = new Random().Next(10, 99);
                while (true)
                {
                    this.BeginInvoke(new Action(() =>
                    {
                        listBox1.Items.Add($"{i}");
                    }));
                    await Task.Delay(3000);
                }
            });
            _Thread1.Start();
            Thread.Sleep(10000);
            _Thread1.Abort();
        }
        catch (Exception ex)
        {
        }

OUTPUT 48 48 48 48 48 48 83 48 83 48 83 48 83

Logic Without Await (below logic works file). Click for View Image

try
        {
            var _Thread1 = new Thread(async () =>
            {
                int i = new Random().Next(10, 99);
                while (true)
                {
                    this.BeginInvoke(new Action(() =>
                    {
                        listBox1.Items.Add($"{i}");
                    }));
                    Thread.Sleep(3000);
                    //await Task.Delay(3000);
                }
            });
            _Thread1.Start();
            Thread.Sleep(10000);
            _Thread1.Abort();
        }
        catch (Exception ex)
        {
        }

OUTPUT. 98 98 98 98 79 79 79 79

I want to abort the thread when it's using AWAIT also.

I can do with CancellationToken/Task, but is there any other way? I want to know why thread is not aborted when AWAIT is used.

Thank you in advance. :)

Stas Ivanov
  • 1,173
  • 1
  • 14
  • 24
  • _"but i don't want to use it"_ - why not? – Fildor Oct 16 '19 at 09:44
  • 11
    `Thread.Abort()` should actually be called `Thread.InsertBugHere()` – Matthew Watson Oct 16 '19 at 09:46
  • 1
    BTW: [You are using HttpClient wrong](https://josefottosson.se/you-are-probably-still-using-httpclient-wrong-and-it-is-destabilizing-your-software/) – Fildor Oct 16 '19 at 09:46
  • 3
    Why are you using a Thread in the first place? – Fildor Oct 16 '19 at 09:47
  • Thanks @Fildor, I can go with Task and CancellationToken but I want to know that Why Abort not working while AWAIT in Thread. Why it not Aborting Thread while I call Abort Method. – Ashish Sojitra Oct 16 '19 at 09:58
  • You need to put the code in the question - a lot of people (myself included) are blocked from viewing the images by their work firewall... – Matthew Watson Oct 16 '19 at 09:59
  • Let me update it. Thank you. – Ashish Sojitra Oct 16 '19 at 10:01
  • @AshishSojitra there's no `await` anywhere in the code while the threads do nothing but try to call back into the UI thread. Looks like you removed *everything* relevant and left just buggy code in the question. – Panagiotis Kanavos Oct 16 '19 at 10:13
  • 1
    The `Thread.Abort` aborts the thread that originally began the task (or it would if it was still running, which it's not), not the thread(s) that end up running the task continuations. You can't mix and match, here -- use cooperative cancellation for tasks and events for threads (never, ever `Abort`). – Jeroen Mostert Oct 16 '19 at 10:14
  • 1
    If you call `await Task.Delay(3000);` on a non-UI thread, then it is probably going to be called back on a different thread - and that isn't going to be the thread that you aborted. – Matthew Watson Oct 16 '19 at 10:15
  • 3
    @AshishSojitra remove *every* call to `Thread`, every attempt to call `BeginInvoke`. Just use `async void Button1_Click(..){ ...; var result= await client.GetStringAsync(someUrl); textBox1.Text=result;...}` – Panagiotis Kanavos Oct 16 '19 at 10:15
  • @AshishSojitra the way the question is right now it should be closed as `unclear`. The code does nothing useful and doesn't even match the question itself – Panagiotis Kanavos Oct 16 '19 at 10:16
  • 2
    @AshishSojitra as for aborting, don't. Use a CancellationTokenSource, pass the cancellation token to every async method that accepts one, and signal it when you need to cancel the method. – Panagiotis Kanavos Oct 16 '19 at 10:18
  • 2
    There are a number of cases where Thread.Abort() has no effect. But no need to dig deep, it is a very simple case here. The thread isn't running anymore. All that it does is get the async code to start executing, takes a very small fraction of a millisecond. Mixing Thread and async is not a good idea, you just don't need async at all when code is already running on a worker thread. Do favor Task. – Hans Passant Oct 16 '19 at 10:35
  • I know my question is look like unclear and i have done wrong and I have mixed up Thread with async and await in code logic, but I want to know that why Abort not stop all process of that thread? After abort it still sending data to UI. So is there Await create New Thread? Which is not related to aborted thread? – Ashish Sojitra Oct 16 '19 at 10:55
  • 1
    [There is no thread.](https://blog.stephencleary.com/2013/11/there-is-no-thread.html) Thread1 which you are trying to abort, as stated several times before, is not running anymore by the time you try to abort it. – Fildor Oct 16 '19 at 10:58

1 Answers1

1

I suppose the reason for the behavior you are observing is that the continuation for the asynchronous operation is scheduled on a ThreadPool thread. So, even though you have aborted the thread your code was running on initially, the continuation was scheduled and then executed on a different thread.

As it was already mentioned in the comments, you should never combine explicit Thread usage with async / await. Moreover, for all new code you are writing async / await is the preferred approach.

Here is the link to an answer by Stephen Cleary which clarifies this a bit more.

Stas Ivanov
  • 1,173
  • 1
  • 14
  • 24
  • @HansPassant, you're right about the article, it's more about I/O-bound calls. I'll find a better suiting material and update my answer. Thanks! – Stas Ivanov Oct 16 '19 at 13:14
  • @HansPassant I've updated my answer. Please let me know if it needs further improvement. – Stas Ivanov Oct 16 '19 at 14:06