none
backgroundWorker & semaphore combination producing 'busy' error RRS feed

  • Question

  • I'm doing some work using a background worker that generates clues for a crossWord puzzle.

    the background workers

    (2x for clue generating

      1. goes through all the words in puzzle and generates their clues

      2. generates the clues requested by the user which the 1st background worker did not yet do)

    they're both defined in the main form and have their own semaphores to stall form-disposal until they've both cancelled.

    the 1st one (that does them all in sequence) is called either by the menu-Load or menu-New events which look like this (irrelevant code excised)

    void mnuLoad_click(object sender, EventArgs e)
    {
        OpenFileDialog ofd = new OpenFileDialog();
        ofd.Title = "Load crossword puzzle.";
        ofd.Filter = ".xml|*.xml";
        if (ofd.ShowDialog() == DialogResult.OK)
        {
            string strCW_GeneratorFilename = (System.IO.Directory.GetCurrentDirectory() + "\\" + classCW_XML.strCW_Generator_Filename).ToUpper();
       
            cPuzzle = classCW_XML.instance.File_Load(ofd.FileName);
      
            drawPuzzle();
    
            bckCW_ClueWriter_All.CancelAsync();
            semCW_ClueWriter_All.WaitOne();
            bckCW_ClueWriter_All.RunWorkerAsync();
            semCW_ClueWriter_All.Release();
    
        }
    }


    works fine.  until I try to quickly load a second game before the bckCW_ClueWriter_All worker has completed its task.  It waits for the semaphore to say its done quitting and then gets an error(

    System.InvalidOperationException
      HResult=0x80131509
      Message=This BackgroundWorker is currently busy and cannot run multiple tasks concurrently.
      Source=System
      StackTrace:
       at System.ComponentModel.BackgroundWorker.RunWorkerAsync(Object argument)
       at System.ComponentModel.BackgroundWorker.RunWorkerAsync()
       at CrosswordPuzzle.formCrosswordPuzzle.mnuLoad_click(Object sender, EventArgs e) in C:\C#\CrosswordPuzzle\CrosswordPuzzle\formCrosswordPuzzle.cs:line 577
       at System.Windows.Forms.MenuItem.OnClick(EventArgs e)
       at System.Windows.Forms.MenuItem.MenuItemData.Execute()
       at System.Windows.Forms.Command.Invoke()
       at System.Windows.Forms.Command.DispatchID(Int32 id)
       at System.Windows.Forms.Control.WmCommand(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at CrosswordPuzzle.Program.Main() in C:\C#\CrosswordPuzzle\CrosswordPuzzle\Program.cs:line 19

    when it tries to start again.  Any idea?
    BadButBit



    my code is perfect until i don't find a bug

    Thursday, February 28, 2019 5:35 PM

Answers

  • I got it.

    I used a boolean in combination with the work-complete event to relaunch it.

    bolBckCW_ClueWriter_All_StartAgain = true;
    bckCW_ClueWriter_All.CancelAsync();
    if (!bckCW_ClueWriter_All.IsBusy)
    {
        bolBckCW_ClueWriter_All_StartAgain = false;
        classMySemaphore.classSemaphoreState cSemState = semCW_ClueWriter_All.WaitOne();
        bckCW_ClueWriter_All.RunWorkerAsync();
        cSemState = semCW_ClueWriter_All.Release();
    }
    

    and

    bool bolBckCW_ClueWriter_All_StartAgain = false;
    private void BckCW_ClueWriter_All_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (bolBckCW_ClueWriter_All_StartAgain)
        {
            bolBckCW_ClueWriter_All_StartAgain = false;
            classMySemaphore.classSemaphoreState cSemState = semCW_ClueWriter_All.WaitOne();
            bckCW_ClueWriter_All.RunWorkerAsync();
            cSemState = semCW_ClueWriter_All.Release();
                    
        }
    }

    if you see any potential issues with this implementation, I'd be grateful to hear it.

    BadButBit


    my code is perfect until i don't find a bug

    Thursday, February 28, 2019 5:57 PM

All replies

  • I got it.

    I used a boolean in combination with the work-complete event to relaunch it.

    bolBckCW_ClueWriter_All_StartAgain = true;
    bckCW_ClueWriter_All.CancelAsync();
    if (!bckCW_ClueWriter_All.IsBusy)
    {
        bolBckCW_ClueWriter_All_StartAgain = false;
        classMySemaphore.classSemaphoreState cSemState = semCW_ClueWriter_All.WaitOne();
        bckCW_ClueWriter_All.RunWorkerAsync();
        cSemState = semCW_ClueWriter_All.Release();
    }
    

    and

    bool bolBckCW_ClueWriter_All_StartAgain = false;
    private void BckCW_ClueWriter_All_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (bolBckCW_ClueWriter_All_StartAgain)
        {
            bolBckCW_ClueWriter_All_StartAgain = false;
            classMySemaphore.classSemaphoreState cSemState = semCW_ClueWriter_All.WaitOne();
            bckCW_ClueWriter_All.RunWorkerAsync();
            cSemState = semCW_ClueWriter_All.Release();
                    
        }
    }

    if you see any potential issues with this implementation, I'd be grateful to hear it.

    BadButBit


    my code is perfect until i don't find a bug

    Thursday, February 28, 2019 5:57 PM
  • Hi BadButBit,

    Thanks for your sharing.

    If your question has been solved, please mark the useful reply as answer to close the thread. This will make answer searching easier in the forum and be beneficial to community members.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, March 1, 2019 5:36 AM
    Moderator