Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Thread-safe Access to Form Controls

Thread-safe Access to Form Controls

Scheduled Pinned Locked Moved C#
helpcsharpcomquestion
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    LighthouseJ
    wrote on last edited by
    #1

    I'm trying to create a program to make thread-safe calls to form controls, specifically to instances of ToolStripStatusLabel and ToolStripProgressBar. I ran cross this page when VC# told me I was unsafely calling the control. The problem is those two classes aren't derived from Control and don't have the InvokeRequired property. I tried using the forms' own InvokeRequired but it's not working and I don't know what to do. Anyone have any help?

    J 1 Reply Last reply
    0
    • L LighthouseJ

      I'm trying to create a program to make thread-safe calls to form controls, specifically to instances of ToolStripStatusLabel and ToolStripProgressBar. I ran cross this page when VC# told me I was unsafely calling the control. The problem is those two classes aren't derived from Control and don't have the InvokeRequired property. I tried using the forms' own InvokeRequired but it's not working and I don't know what to do. Anyone have any help?

      J Offline
      J Offline
      Judah Gabriel Himango
      wrote on last edited by
      #2

      // On a background thread
      toolStripProgressBar1.Owner.Invoke((ThreadStart)delegate
      {
      toolStripProgressBar1.Value = 50;
      });

      Rather than using Invoke/BeginInvoke, you might want to use the System.ComponentModel.BackgroundWorker class, which raises events for you on the appropriate thread, handling all the Invoke/BeginInvoke for you.

      Tech, life, family, faith: Give me a visit. I'm currently blogging about: Connor's Christmas Spectacular! Judah Himango

      L 1 Reply Last reply
      0
      • J Judah Gabriel Himango

        // On a background thread
        toolStripProgressBar1.Owner.Invoke((ThreadStart)delegate
        {
        toolStripProgressBar1.Value = 50;
        });

        Rather than using Invoke/BeginInvoke, you might want to use the System.ComponentModel.BackgroundWorker class, which raises events for you on the appropriate thread, handling all the Invoke/BeginInvoke for you.

        Tech, life, family, faith: Give me a visit. I'm currently blogging about: Connor's Christmas Spectacular! Judah Himango

        L Offline
        L Offline
        LighthouseJ
        wrote on last edited by
        #3

        that's interesting, thanks. I unfortunately got an exception saying not enough arguments were supplied so I added in my arguments for the delegates like this:

        _statusbar.Owner.Invoke((ThreadEvent)delegate
        {
          _statusbar.Text = "test test, started work";
        }, new Object[] { this, ThreadEventArgs("test message", 0, TheadStatusType.thread_started) });

        In my original delegate, I had it declared object, ThreadEventArgs so I guess that's what it wanted. This works, and without the form-side needing a delegate. Is that the best though? With it like this, it requires a status bar to exist in order to work. I liked the idea of triggering an event and the form can receive it if it wants to and deal with it as it sees fit.

        L J 2 Replies Last reply
        0
        • L LighthouseJ

          that's interesting, thanks. I unfortunately got an exception saying not enough arguments were supplied so I added in my arguments for the delegates like this:

          _statusbar.Owner.Invoke((ThreadEvent)delegate
          {
            _statusbar.Text = "test test, started work";
          }, new Object[] { this, ThreadEventArgs("test message", 0, TheadStatusType.thread_started) });

          In my original delegate, I had it declared object, ThreadEventArgs so I guess that's what it wanted. This works, and without the form-side needing a delegate. Is that the best though? With it like this, it requires a status bar to exist in order to work. I liked the idea of triggering an event and the form can receive it if it wants to and deal with it as it sees fit.

          L Offline
          L Offline
          LighthouseJ
          wrote on last edited by
          #4

          I think I found the problem with what I was doing originally, I don't think I was invoking the delegate right. I ran across this page which talks about BeginInvoke. I used the section of code declared as the typical way of using BeginInvoke as my inspiration and got my invoke working pretty well. I thought anyone reading this and interested in a fix might want to know.

          1 Reply Last reply
          0
          • L LighthouseJ

            that's interesting, thanks. I unfortunately got an exception saying not enough arguments were supplied so I added in my arguments for the delegates like this:

            _statusbar.Owner.Invoke((ThreadEvent)delegate
            {
              _statusbar.Text = "test test, started work";
            }, new Object[] { this, ThreadEventArgs("test message", 0, TheadStatusType.thread_started) });

            In my original delegate, I had it declared object, ThreadEventArgs so I guess that's what it wanted. This works, and without the form-side needing a delegate. Is that the best though? With it like this, it requires a status bar to exist in order to work. I liked the idea of triggering an event and the form can receive it if it wants to and deal with it as it sees fit.

            J Offline
            J Offline
            Judah Gabriel Himango
            wrote on last edited by
            #5

            Like I said, BackgroundWorker is really want you should look at:

            backgroundWorker1.DoWork += MyWorkerFunction;
            backgroundWorker1.ProgressChanged += MyProgressReported;
            backgroundWorker1.RunWorkerCompleted += MyWorkCompleted;

            backgroundWorker1.RunAsync(someArgument); // this will fire the DoWork event

            void MyWorkerFunction(object sender, DoWorkEventArgs e)
            {
            // this is event handler is called on the background thread.
            ...
            // report some progress on the UI thread
            backgroundWorker1.ReportProgress(99);
            ...
            // When this method finishes, the RunWorkerCompleted event will be fired on the UI thread.
            }

            void MyProgressReported(object sender, ProgressReportedEventArgs e)
            {
            // this event handler is fired on the UI thread whenever worker.ReportProgress(progressVal, optionalObject) is called
            }

            void MyWorkCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
            // This event handler is called on the UI thread.
            }

            Tech, life, family, faith: Give me a visit. I'm currently blogging about: Connor's Christmas Spectacular! Judah Himango

            L 1 Reply Last reply
            0
            • J Judah Gabriel Himango

              Like I said, BackgroundWorker is really want you should look at:

              backgroundWorker1.DoWork += MyWorkerFunction;
              backgroundWorker1.ProgressChanged += MyProgressReported;
              backgroundWorker1.RunWorkerCompleted += MyWorkCompleted;

              backgroundWorker1.RunAsync(someArgument); // this will fire the DoWork event

              void MyWorkerFunction(object sender, DoWorkEventArgs e)
              {
              // this is event handler is called on the background thread.
              ...
              // report some progress on the UI thread
              backgroundWorker1.ReportProgress(99);
              ...
              // When this method finishes, the RunWorkerCompleted event will be fired on the UI thread.
              }

              void MyProgressReported(object sender, ProgressReportedEventArgs e)
              {
              // this event handler is fired on the UI thread whenever worker.ReportProgress(progressVal, optionalObject) is called
              }

              void MyWorkCompleted(object sender, RunWorkerCompletedEventArgs e)
              {
              // This event handler is called on the UI thread.
              }

              Tech, life, family, faith: Give me a visit. I'm currently blogging about: Connor's Christmas Spectacular! Judah Himango

              L Offline
              L Offline
              LighthouseJ
              wrote on last edited by
              #6

              I looked at BackgroundWorker after you said it and concluded that using it would require a lot of rewiring of my program, more than I was willing to do. However, I do now know it exists and I'll keep it in mind next time around.

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups