Home > Software design >  Exit a method that contains an invoke command
Exit a method that contains an invoke command

Time:07-26

I have a method that runs some tasks in the background called backgroundworker5_doWork(). This method call the Invoke instruction which helps me to access the controls on my windows form (since a control cannot be accessed from another thread normally) as such

 private void backgroundWorker5_DoWork(object sender, DoWorkEventArgs e)
    {
        if(!isAdmin)
        {             
            //Start of invoke instruction   
            Invoke(new Action(() =>
            {
                if(test)
                {
                    return;
                }

                if (ValidateAll())
                {
                    comboBox5.Items.Clear();
                    packageToSendList.Clear();
                    progressBar3.Visible = true;
                    Cursor.Current = Cursors.WaitCursor;
                }

            }));
            //End of invoke

            RunAfterInvokeMethod() //Instructions called after the invoke 
       }
   }

My issue is that when true, the return instruction exits the invoke block (rightfully so) and executes the RunAfterInvokeMethod() which is not what I want. What I want is to exit the backgroundWorker5_doWork() method after the return is called.

I understand that it only exits the invoke instruction but is it possible to make it exit the parent method as well ? Maybe using other instructions ?

Thanks !

CodePudding user response:

You can return a value (in this case, bool) from an invoked delegate:

bool result = (bool) Invoke(new Func<bool>(() =>
{
    if(test)
    {
        return false;
    }

    if (ValidateAll())
    {
        comboBox5.Items.Clear();
        packageToSendList.Clear();
        progressBar3.Visible = true;
        Cursor.Current = Cursors.WaitCursor;
    }

   return true;
}));
//End of invoke

if (result)
{
    RunAfterInvokeMethod() //Instructions called after the invoke 
}

CodePudding user response:

You can create a bool to help you with that, something like

private void backgroundWorker5_DoWork(object sender, DoWorkEventArgs e)
{
    if(!isAdmin)
    {             
        //Start of invoke instruction   
        bool doThis = true;
        Invoke(new Action(() =>
        {
            if(test)
            {
                doThis = false;
                return;
            }

            if (ValidateAll())
            {
                comboBox5.Items.Clear();
                packageToSendList.Clear();
                progressBar3.Visible = true;
                Cursor.Current = Cursors.WaitCursor;
            }

        }));
        //End of invoke
        if(doThis)
            RunAfterInvokeMethod(); //Instructions called after the invoke 
   }
 }

CodePudding user response:

The answer by aca would be the simplest solution.

I would however argue for rewriting your method to use async/await, since this makes it much easier to run code on a background thread while still updating the UI on the UI thread.

var result = await Task.Run(MyBackgroundWork);
UpdateMyUI(result); // continue on the UI thread once MyBackgroundWork has completed

If you want to do some more background work after updating the UI you can always do another Task.Run after updating the UI to schedule some more work to be run.

  • Related