0

I want to stop BackgroundWorker when click stop button, the Background Worker execute callback function to show message.

I'm trying stop in BackgroundWorker DoWork(), but doesn't work, how should do it?

WorkerSupportsCancellation is true.

    private void ShowDebug(string msg)
    {
        this.Invoke(new Action( () => { txtBoxDebug.AppendText(msg); }));
        this.Invoke(new Action( () => { txtBoxDebug.AppendText(Environment.NewLine); }));            
    }

    private void BtnTest(object sender, EventArgs e)
    {
        if (cbBoxAdapterList.SelectedIndex == -1)
        {
            ShowDebug("Select an adapter");
            return;
        }
        selectDevice = allDevices[cbBoxAdapterList.SelectedIndex];
        bkgrdTest.RunWorkerAsync();
    }

    private void BkgrdTestDoWork(object sender, DoWorkEventArgs e)
    {
        using (PacketCommunicator communicator = selectDevice.Open(65536, PacketDeviceOpenAttributes.Promiscuous, 1000))
        {
            ShowDebug("Begin Capture");

            communicator.ReceivePackets(0, PacketHandlerTest);

            if (bkgrdTest.CancellationPending == true)
            {
                e.Cancel = true;
                return;
            }
        }
        
    } 
    private void PacketHandlerTest(Packet packet)
    {
        ShowDebug("Packet length: " + packet.Length.ToString());
        Thread.Sleep(500);
    }

    private void BtnStop(object sender, EventArgs e)
    {
        if (bkgrdTest.IsBusy)
        {
            bkgrdTest.CancelAsync();
        }
    }
Rain
  • 105
  • 1
  • 2
  • 7
  • "but doesn't work" what happens? Have you set a breakpoint on `if (bkgrdTest.CancellationPending == true)` which by the way could be shortened to `if (bkgrdTest.CancellationPending)` The `BackgroundWorker` will not unilaterally abort the call to `communicator.ReceivePackets`, it will only abort if you check `CancellationPending` within that. Is there any reason why you are using `BackgroundWorker` anyway, and not Tasks? – Charlieface Mar 03 '22 at 11:53
  • I mean when click BtnStop, the bkgrdTest sholud be stop working. – Rain Mar 03 '22 at 11:57
  • Perhaps within `PacketHandlerTest` you should check for cancellation and call `PacketCommunicator.Break`. As I said. `BackgroundWorker` will not abort for you. It merely shows you that cancellation was requested, you need to check and abort yourself – Charlieface Mar 03 '22 at 11:58
  • I don't know which way to use, use BackgrounWorker or Tasks to execute communicator.ReceivePackets – Rain Mar 03 '22 at 12:00
  • @Charlieface Sorry I still don't know what to do, can you help me? – Rain Mar 03 '22 at 12:33
  • 1
    Possible [duplicate](https://stackoverflow.com/q/33191015/5114784)? Btw, `CancelAsync` just sets the `CancellationPending` that you must poll often enough. It will not just automagically stop any operation (I guess your `Thread.Sleep` just represents some processing but you must poll the cancellation request even inside such an operation). – György Kőszeg Mar 03 '22 at 12:33
  • 1
    Is `communicator.ReceivePackets(0, PacketHandlerTest);` blocking the thread? – Jeroen van Langen Mar 03 '22 at 12:44
  • `Task` is the more modern way of doing it. Whichever you choose, you *must* do the cancellation yourself. Looking at the source code: yes `communicator.ReceivePackets` calls through to the `pcap` native library and blocks, but you can poll `CancellationPending ` in the callback. @JeroenvanLangen – Charlieface Mar 03 '22 at 12:44

0 Answers0