Multithreading cancellation

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • airwot4

    Multithreading cancellation

    I have the below code for a multithreaded winforms application. It
    works successfully apart from the cancel function.

    AppendLog2 has an out parameter which should return true if either of
    two conditions are met (to cancel operation). This parameter is not
    being passed back when AppendLog2 invokes itself, which is everytime
    due to the operation.

    Any ideas how I could better accomplish this? I followed this article:


    Thanks



    private void btnFSearch_Clic k_1(object sender, EventArgs e)
    {
    //Starts search operation or cancels running operation
    ....
    switch (_state)
    {
    case RunState.Idle:
    _state = RunState.Runnin g;
    btnFSearch.Text = "Cancel";

    FSearchDeleteDe legate delMain = new
    FSearchDeleteDe legate(FileExis tsLoop);
    delMain.BeginIn voke(arComputer s, txtFSearch.Text , null, null);
    break;

    case RunState.Runnin g:
    _state = RunState.Cancel led;
    btnFSearch.Enab led = false;
    break;

    case RunState.Cancel led:
    MessageBox.Show ("Operation currently cancelling");
    break;
    }
    }

    public void FileExistsLoop( ArrayList arComputers, string
    strFileSearchPa th)
    {
    //Loops through arComputers and logs back to main UI.
    bool cancel = false;
    AppendLog2("Che cking existance of " + strFileSearchPa th + " on " +
    arComputers.Cou nt + " computers.", out cancel);
    foreach (string strComputer in arComputers)
    {
    if (cancel) break;
    if (Functions.Ping Test(strCompute r))
    {
    if (Functions.File Exists(strCompu ter, strFileSearchPa th))
    AppendLog2(strC omputer + " = file exists", out cancel);
    else
    AppendLog2(strC omputer + " = file not found", out cancel);
    }
    else
    AppendLog2(strC omputer + " is not responding to ping requests",
    out cancel);
    }
    AppendLog2("*** Finished***", out cancel);
    }

    public void AppendLog2(stri ng log, out bool cancel)
    {
    if (txtOutput.Invo keRequired)
    {
    LogDelegate2 delInstance = new LogDelegate2(Ap pendLog2);
    object inoutCancel = false;

    Invoke(delInsta nce, new object[] { log, inoutCancel });

    cancel = (bool)inoutCanc el;
    }
    else
    {
    //Check for cancel
    cancel = (_state == RunState.Cancel led);

    // Check for completion
    if (cancel || (log == "***Finished*** "))
    {
    _state = RunState.Idle;
    cancel = true;
    ...
    }

    ...
    }
    return;
    }
  • Marc Gravell

    #2
    Re: Multithreading cancellation

    Personally I'd look at BackgroundWorke r in this case, using CancelAsync
    to request a cancel, with the worker code checking CancellationPen ding
    to see if it should exit. This then handles all the grunge for you...

    Marc

    Comment

    • qglyirnyfgfo@mailinator.com

      #3
      Re: Multithreading cancellation

      Well, its kind of convoluted to explain but your problem basically
      lies on your boxing and un-boxing of the Boolean (value type)
      variable.

      You box when you call “object inoutCancel = false” you un-box when you
      call the “public void AppendLog2(stri ng log, out bool cancel)”
      function etc.

      I think you should do what Mark is suggesting but if you want to live
      things the way they are you could at least change the Boolean cancel
      variable to an object such as CancelEventArgs sot that you don’t have
      to worry about boxing and un-boxing.

      I hacked your exaple and made one of my own using CancelEventArgs so
      that you can get the picture:

      ------------------------------

      delegate void LogDelegate2(st ring log, CancelEventArgs cancel);

      public partial class Form1 : Form
      {
      public Form1()
      {
      InitializeCompo nent();

      new Thread(DoIt).St art();
      }

      void DoIt()
      {
      CancelEventArgs cancel = new CancelEventArgs ();
      AppendLog2("aaa a", cancel);
      }

      public void AppendLog2(stri ng log, CancelEventArgs cancel)
      {
      if (this.InvokeReq uired)
      {
      LogDelegate2 delInstance = new LogDelegate2(Ap pendLog2);
      Invoke(delInsta nce, new object[] { log, cancel });

      bool cancelVal = cancel.Cancel;
      }
      else
      {
      cancel.Cancel = true;
      }

      return;
      }
      }


      On Jun 6, 7:26 am, airwot4 <neale...@gmail .comwrote:
      I have the below code for a multithreaded winforms application. It
      works successfully apart from the cancel function.
      >
      AppendLog2 has an out parameter which should return true if either of
      two conditions are met (to cancel operation). This parameter is not
      being passed back when AppendLog2 invokes itself, which is everytime
      due to the operation.
      >
      Any ideas how I could better accomplish this? I followed this article:http://msdn.microsoft.com/en-us/library/ms951109.aspx
      >
      Thanks
      >
      private void btnFSearch_Clic k_1(object sender, EventArgs e)
      {
      //Starts search operation or cancels running operation
      ...
        switch (_state)
        {
          case RunState.Idle:
            _state = RunState.Runnin g;
            btnFSearch.Text = "Cancel";
      >
            FSearchDeleteDe legate delMain = new
      FSearchDeleteDe legate(FileExis tsLoop);
            delMain.BeginIn voke(arComputer s, txtFSearch.Text , null, null);
            break;
      >
          case RunState.Runnin g:
            _state = RunState.Cancel led;
            btnFSearch.Enab led = false;
            break;
      >
          case RunState.Cancel led:
            MessageBox.Show ("Operation currently cancelling");
            break;
          }
      >
      }
      >
      public void FileExistsLoop( ArrayList arComputers, string
      strFileSearchPa th)
      {
      //Loops through arComputers and logs back to main UI.
        bool cancel = false;
        AppendLog2("Che cking existance of " + strFileSearchPa th + " on " +
      arComputers.Cou nt + " computers.", out cancel);
        foreach (string strComputer in arComputers)
        {
          if (cancel) break;
          if (Functions.Ping Test(strCompute r))
          {
            if (Functions.File Exists(strCompu ter, strFileSearchPa th))
              AppendLog2(strC omputer + " = file exists", out cancel);
            else
              AppendLog2(strC omputer + " = file not found", out cancel);
          }
          else
            AppendLog2(strC omputer + " is not responding to ping requests",
      out cancel);
        }
        AppendLog2("*** Finished***", out cancel);
      >
      }
      >
      public void AppendLog2(stri ng log, out bool cancel)
      {
        if (txtOutput.Invo keRequired)
        {
          LogDelegate2 delInstance = new LogDelegate2(Ap pendLog2);
          object inoutCancel = false;
      >
          Invoke(delInsta nce, new object[] { log, inoutCancel });
      >
          cancel = (bool)inoutCanc el;
         }
         else
         {
            //Check for cancel
            cancel = (_state == RunState.Cancel led);
      >
            // Check for completion
            if (cancel || (log == "***Finished*** "))
            {
              _state = RunState.Idle;
              cancel = true;
              ...
            }
      >
             ...
          }
        return;
      >
      >
      >
      }- Hide quoted text -
      >
      - Show quoted text -

      Comment

      • Marc Gravell

        #4
        Re: Multithreading cancellation

        Re boxing - actually, I suspect it relates more to not getting the value
        back out of the array here:

        object inoutCancel = false;
        Invoke(delInsta nce, new object[] { log, inoutCancel });
        cancel = (bool)inoutCanc el;

        But to be honest, until you posted I didn't look too much at the
        specific code, preferring to lean towards a much simpler (and proven)
        approach like BackgroundWorke r ;-p

        Marc

        Comment

        • Marc Gravell

          #5
          Re: Multithreading cancellation

          Ignore me - I misread the code anyways!

          But it goes to show the point of using the simplest approach ;-p

          Marc

          Comment

          • qglyirnyfgfo@mailinator.com

            #6
            Re: Multithreading cancellation

            But to be honest, until you posted I didn't look too much at the
            specific code, preferring to lean towards a much simpler (and proven)
            approach like BackgroundWorke r ;-p
            Yeah, post like this are real turn offs because they don’t compile and
            are loooong so it’s hard to get someone to bother trying to figure
            them out.

            If only people posted “Short but complete examples”….. Oops, can I use
            that phrase? Did Jon trade mark that already and I have to pay
            royalties now?? :)



            Comment

            • airwot4

              #7
              Re: Multithreading cancellation

              Thanks for the responses, I'll give BackgroundWorke r a try instead.

              And sorry about the long post, I should have cut it down!

              Comment

              Working...