0

We have a single long(ish) operation in our app, Calculate, which takes about 5 seconds to complete. This post is basically identical to what I am doing, but only considers completed threads. Anything that triggers Calculate should kill any running calc and then restart it. It seems, based on posts like this one, that a ThreadPool could solve this, but might not be the appropriate solution in these one-off cases.

So my question is how to properly dispose of the "old one" if it's still going. I am currently doing...

If CalcThread IsNot Nothing Then
    CalcThread.Abort()
    CalcThread = Nothing
End If
If CalcThread Is Nothing Then 'one assumes this will always be true
    CalcThread = New Threading.Thread(AddressOf InternalCalculate)
    CalcThread.IsBackground = True
End If
CalcThread.Start()

This appears to work, but is this the correct solution?

Update: Given that my use-case is that there is only a single one of these threads, and, as Chris notes below, Abort might not do that immediately, should I be using a SyncLock across the guts of Calculate?

Community
  • 1
  • 1
Maury Markowitz
  • 9,082
  • 11
  • 46
  • 98
  • Here's a good article on the evils of Thread.Abort https://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation – FloatingKiwi Sep 21 '16 at 14:27
  • I have read that article, but it is not a consideration here because there is no shared data or anything else that will be held open. I guess my real question is "can I just set the thread to Nothing and move on"? – Maury Markowitz Sep 21 '16 at 14:39

1 Answers1

1

Don't kill the thread. Declare a volatile boolean variable in a scope that is accessible to both the Calc method and the code which may cancel it. Modify the Calc method to periodically check the variable, and if it is true then exit. To "kill" the thread, just set the variable.

Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • You cannot declare a volatile in VB.net. There are ways to do the same thing, but they are somewhat ugly. As I noted above, there is no shared data between main and the thread, so the .Abort does not appear to be an issue - there's nothing that could be left open. – Maury Markowitz Sep 21 '16 at 14:43
  • Fair enough re: volatile- use a workaround. Thread aborts are bad juju, though- there may not be shared data but what happens to the results of the Calc method? Can aborting the thread leave the output in a half-committed state? – Chris Shain Sep 21 '16 at 14:46
  • It can, but the first thing the new thread will do is empty that state. So what exactly happens if I don't abort and just set it to Nothing? Will it continue running and then disappear on exit? – Maury Markowitz Sep 21 '16 at 14:56
  • Yes it will continue to run unless you abort it or exit the outermost method for the thread. – Chris Shain Sep 21 '16 at 15:44
  • It's also worth noting what abort does: it throws a ThreadAbort exception on the thread, which may be caught and result in unbounded cleanup. So Abort is not a blocking operation. The thread may continue to run indefinitely, even if you Abort() it. – Chris Shain Sep 21 '16 at 15:47
  • Interesting. Thanks Chris, this is very useful info. – Maury Markowitz Sep 21 '16 at 17:37