1

In a program I'm developing, I have two primary threads: the UI thread and a background thread that interfaces with hardware. On the form during the run, I have a pause button that should stop the test until a resume button is clicked. Functionally this means that I want to use the UI thread to suspend the hardware thread, and since Thread.Suspend is deprecated, I'm trying to avoid that.

I tried used an AutoResetEvent, which unfortunately resulted in the UI thread suspending itself, and then locking up the hardware thread when it tried to send a UI update request.

Is there a good way to use one thread to suspend another in VB.NET at any point in execution?


As an aside, I've already looked at Suspend a thread from another thread in VB.NET, and while the question was similar, the answers ended up discussing essentially the inverse situation from what I'm trying to do.


My code is set up so that the multithreading actually occurs through a multithreaded object, and the form makes a call to an asynchronous Run routine within that object. I'll try to provide the most relevant information, but if there are other parts of the code you'd like to see, let me know and I can add them.

In frmRun

'Multithreaded object copied from global to local context
Private currentprofile as MTProfile = Main.testprofile  

'Button click handler to start the run
Private Sub btnRunTest_Click(sender As System.Object, e As System.EventArgs) Handles btnRunTest.Click
    currentprofile.RunAsync()
End Sub

In MTProfile

'Asynchronous call to run subroutine
'_thread1 is a member of the MTProfile class
Public Sub RunAsync()
    _thread1 = New Threading.Thread(AddressOf Run)
    _thread1.IsBackground = True
    _thread1.Start()
End Sub

'Run subroutine
Public Sub Run()
    For i As Integer = 0 To _profile.Count - 1
        'Get information for the action in the profile and carry that action out
        'Actions can last anywhere from 50 s to over 10 minutes
    Next
End Sub

My current thought as to getting the code to pause is to have clicking the pause button on the form raise an event that is caught by the object and asks _thread1 to pause. The two main concerns I have with that are what function I can use to actually get the thread to pause and how to set up the event trigger so that it still allows encapsulation of the class.


As to why I think this question is not a duplicate of Pause/Resume loop in Background worker, there are two main reasons. The most important is that I want to be able to suspend my process at any time rather than after each loop iteration, which I don't think I could do using that solution without putting a WaitOne command after every command in my loop. The second, which I think matters much less, is that I'm manipulating my thread directly rather than using a BackgroundWorker.

Community
  • 1
  • 1
Aliden
  • 441
  • 1
  • 4
  • 15
  • 1
    Without seeing your code, your question is impossible to answer. For instance, why did manipulating a `AutoResetEvent` object "suspend" the UI thread? – Lasse V. Karlsen Jul 11 '14 at 20:18
  • @LasseV.Karlsen It blocked (probably should have used the proper terminology) the UI thread because I did it wrong. Thinking back on it, having the UI thread raise an event and run into a `WaitOne` command was just stupid on my part. – Aliden Jul 12 '14 at 03:35
  • @Aliden: "I want to be able to suspend my process *(you probably meant thread)* at any time rather than after each loop iteration". You can't - plain and simple. The pausing needs to be cooperative, and you were sort of heading down the right path with the `AutoResetEvent` although I'm surprised that you went for that as opposed to `ManualResetEvent`. What version of .NET are you targeting? – Kirill Shlenskiy Jul 12 '14 at 05:38
  • @KirillShlenskiy I did mean thread; my mistake. I was using `AutoResetEvent` instead of `ManualResetEvent` because of a lack of experience. I'm targeting .NET 2.0. Why do you say I can't pause it anywhere? Let's say, for the sake of argument, that I used a `ManualResetEvent` and put a `WaitOne` statement after every line in the `Run` function. Wouldn't that make it so I could block the thread anywhere I could edit my code? – Aliden Jul 12 '14 at 14:45
  • @Aliden, technically yes, but that still does not constitute "suspending the thread at any time". For example, if you make a synchronous call inside your loop, which takes (as per your code comments) between 50s and 10 minutes, your `ManualResetEvent.WaitOne` will not be hit until that synchronous work is fully done, which in some cases can take a long time. If you can't integrate the wait handle into your low-level code which interfaces with the hardware your ability to pause the method's execution up the call chain will be limited due to the presence of those long-running operations. – Kirill Shlenskiy Jul 12 '14 at 23:27
  • @KirillShlenskiy You're absolutely right; it's not. But it may be the closest I can manage. As far as the other options I have, from what I understand, `Suspend` actually stops a thread where it is, and `Resume` picks it up. Can you explain to me why (other than the fact they're deprecated) it's a bad idea to use those functions? – Aliden Jul 13 '14 at 17:16

0 Answers0