0
        checkerThread = new Thread(new ThreadStart(() => CheckTokens()));
        checkerThread.Start();

        // Re-enable controls when done
        stopCheckButton.Visible = false;
        stopCheckButton.Enabled = false;
        startCheckButton.Enabled = true;
        loadTokenListButton.Enabled = true;
        exportTokensButton.Enabled = true;
        clearCheckButton.Enabled = true;
        clearValidButton.Enabled = true;
        tokenInputBox.Enabled = true;

When the thread is running controls are disabled in my Form. I want to re-enable them when the thread is done. How would I do that without blocking the UI by thread.Join()?

9
  • 2
    Have you heard about async/await? Commented Feb 16, 2021 at 21:42
  • 1
    using async / await depends on the type of work that must be done imo. Commented Feb 16, 2021 at 21:46
  • 1
    BackgroundWorker is in the toolbox, you'll like its RunWorkerCompleted event. Commented Feb 16, 2021 at 21:50
  • 2
    Remember - "await" can be like a virus: it can "infect" unrelated parts of your code base with stupid "Async" declarations. Commented Feb 16, 2021 at 21:57
  • 2
    @paulsm4 No, it would only affect related parts of the code base, namely anything that cares about performing an action when the asynchronous operation is finished. And that problem isn't specific to async as a keyword, it's inherent in the operation being asynchronous, which is necessary to not block the UI, even if you use some other form of asynchrony. Commented Feb 16, 2021 at 22:00

1 Answer 1

-1

I suggest consider using a BackgroundWorker

EXAMPLE CODE:

https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/how-to-run-an-operation-in-the-background?view=netframeworkdesktop-4.8

Here's another example:

https://www.dotnetperls.com/backgroundworker-vbnet

public Class Form1

    Public Class ArgumentType
        Public _a As Int32
        Public _b As Int32
    End Class

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Create the argument object.
        Dim args As ArgumentType = New ArgumentType()
        args._a = 5
        args._b = 6
        ' Start up the BackgroundWorker1.
        ' ... Pass argument object to it.
        BackgroundWorker1.RunWorkerAsync(args)
    End Sub

    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, _
                                         ByVal e As System.ComponentModel.DoWorkEventArgs) _
                                         Handles BackgroundWorker1.DoWork
        ' Do some time-consuming work on this thread.
        System.Threading.Thread.Sleep(1000)
        ' Get argument.
        Dim args As ArgumentType = e.Argument
        ' Return value based on the argument.
        e.Result = args._a * args._b
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, _
                                                     ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
                                                     Handles BackgroundWorker1.RunWorkerCompleted
        ' Called when the BackgroundWorker is completed.
        MessageBox.Show(e.Result.ToString())
    End Sub
End Class
Sign up to request clarification or add additional context in comments.

4 Comments

@Janic - as Frederik Gheysels said, "using async / await depends on the type of work that must be done imo". I think BackgroudWorker is probably better suited for your needs. Q: You said "C#" in your title... but VB.Net in your tags. Which is it? Both examples should easily translate to either language :)
@Janic if you are going to learn something, don't learn obsolete backgroundworker. Learn async/await.
@paulsm4 await is a more generalized tool than BGW. await can do everything a BGW can do, a BGW can't do everything await can do. You'd only solve the problem with await differently than awaiting a single call to Task.Run if it were a problem that BGW isn't suitable for at all.
@Janic - I believe "newer" isn't necessarily "better". BackgroundWorker is perfectly appropriate here. And "await" CAN be like a virus: it can "infect" unrelated parts of your code base with otherwise unnecessary "Async" declarations. Please consider "upvoting" and/or "accepting" this reply if it helps.