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. .NET (Core and Framework)
  4. Issue with threading behaviour ... I think

Issue with threading behaviour ... I think

Scheduled Pinned Locked Moved .NET (Core and Framework)
csharpdatabasewinformsdesignhelp
4 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.
  • J Offline
    J Offline
    Jack Vanderhorst
    wrote on last edited by
    #1

    I have a class, call it Inventory, it does some basic database tasks using a BackgroundWorker like SaveChanges(), LoadFirstItem() etc. In my RunWorkerCompleted method PropertyChanged events are fired to notify the UI to update itself. This works swimmingly in my WinForms app and the BackGroundWorker is clearly doing it's thing successfully, but I'm having trouble writing [TestMethod()]'s for the class in a test project. In a test project, it seems like after calling RunWorkerAsync the DoWork method doesn't get called, and as a result neither does RunWorkerCompleted, and my tests always fail. Breakpoints in DoWork or RunWorkerCompleted are not hit. I assumed this was because my test method was not waiting for the background thread to finish so I've tried sleeping the main thread to see if the BackgroundWorker can catch up, I've tried the Application.DoEvents() thing, but I'm a bit of a rookie in the threading department... and the authoring of Unit Tests department for that matter! uh oh :) Any pointers on how to please my BackgroundWorker in a [TestMethod()]?

    L 1 Reply Last reply
    0
    • J Jack Vanderhorst

      I have a class, call it Inventory, it does some basic database tasks using a BackgroundWorker like SaveChanges(), LoadFirstItem() etc. In my RunWorkerCompleted method PropertyChanged events are fired to notify the UI to update itself. This works swimmingly in my WinForms app and the BackGroundWorker is clearly doing it's thing successfully, but I'm having trouble writing [TestMethod()]'s for the class in a test project. In a test project, it seems like after calling RunWorkerAsync the DoWork method doesn't get called, and as a result neither does RunWorkerCompleted, and my tests always fail. Breakpoints in DoWork or RunWorkerCompleted are not hit. I assumed this was because my test method was not waiting for the background thread to finish so I've tried sleeping the main thread to see if the BackgroundWorker can catch up, I've tried the Application.DoEvents() thing, but I'm a bit of a rookie in the threading department... and the authoring of Unit Tests department for that matter! uh oh :) Any pointers on how to please my BackgroundWorker in a [TestMethod()]?

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Hi Jack, Not sure, but I would guess your test framework is being run from some thread other than the main thread. BackgroundWorker (and other threads) are not allowed to touch GUI Controls directly, you know that. Some of their events (ReportProgress and RunWorkCompleted) take care of the thread barrier automatically, but only so when the BackgroundWorker got created by the main thread. Weird things could happen when an arbitrary thread creates a BGW whose event handlers in turn try to modify the GUI. To make sure whether your DoWork method gets called or not, I suggest you simply insert a MessageBox.Show(), that one doesn't care about thread boundaries at all. An alternative diagnostic tool is:

      Console.WriteLine("Method XYZ running on thread "+Thread.CurrentThread.ManagedThreadId.ToString("X2"));

      which allows you to visualize the thread on which the caller is running. :)

      Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


      Getting an article published on CodeProject now is hard and not sufficiently rewarded.


      J 1 Reply Last reply
      0
      • L Luc Pattyn

        Hi Jack, Not sure, but I would guess your test framework is being run from some thread other than the main thread. BackgroundWorker (and other threads) are not allowed to touch GUI Controls directly, you know that. Some of their events (ReportProgress and RunWorkCompleted) take care of the thread barrier automatically, but only so when the BackgroundWorker got created by the main thread. Weird things could happen when an arbitrary thread creates a BGW whose event handlers in turn try to modify the GUI. To make sure whether your DoWork method gets called or not, I suggest you simply insert a MessageBox.Show(), that one doesn't care about thread boundaries at all. An alternative diagnostic tool is:

        Console.WriteLine("Method XYZ running on thread "+Thread.CurrentThread.ManagedThreadId.ToString("X2"));

        which allows you to visualize the thread on which the caller is running. :)

        Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


        Getting an article published on CodeProject now is hard and not sufficiently rewarded.


        J Offline
        J Offline
        Jack Vanderhorst
        wrote on last edited by
        #3

        First of all, sorry for the tardy reply. With your suggestion I was able to confirm DoWork was running, the Test Framework was on thread 12, DoWork was on 14. Now I'm wondering, if the BackGroundWorker only knows how to notify the "main" thread, and the Test Framework is not on the main thread, doesn't that mean I'm sort of stuck with testing this BackGroundWorker business? Since I know the DoWork methods are running I suppose I could run a separate set of tests to confirm their results, but ick :) Or, maybe I could ditch the BackGroundWorker and code the necessary threading behaviour myself? Do you think I could work around my issue in this way?

        L 1 Reply Last reply
        0
        • J Jack Vanderhorst

          First of all, sorry for the tardy reply. With your suggestion I was able to confirm DoWork was running, the Test Framework was on thread 12, DoWork was on 14. Now I'm wondering, if the BackGroundWorker only knows how to notify the "main" thread, and the Test Framework is not on the main thread, doesn't that mean I'm sort of stuck with testing this BackGroundWorker business? Since I know the DoWork methods are running I suppose I could run a separate set of tests to confirm their results, but ick :) Or, maybe I could ditch the BackGroundWorker and code the necessary threading behaviour myself? Do you think I could work around my issue in this way?

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          There is no need to ditch the BackgroundWorker at all; when a BGW is created by the main thread, one of its major advantages is its ReportProgress and RunWorkCompleted events run on the main thread too; when created elsewhere, you loose that advantage, but that is what regular threads do all the time. So you would have to explicitly call Control.InvokeRequired and Control.Invoke to get the results towards your GUI, as if your BGW where just another thread. See e.g. here[^] for details, in case you need a refresh. There might be an alternative, fiddling with SynchronizationContexts, but I'm not familiar with that. :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]


          Getting an article published on CodeProject should be easier and faster.


          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