How to avoid starvation of the main thread?

I am making a patch to solve a progress bar problem in an application that is a bit messy. Cancel on progress bar, used to execute Thread.Aborton a thread that does heavy work. I changed this to raising the cancel flag, which I can check at a strategic location in the stream.

In most cases, it works fine, but revocation does not work at all from time to time. I suppose I could have done Application.DoEventsbefore looking at the flag status (there is no risk of re-entry), but I would like a more “clean” option.

I would be grateful if someone could provide me with information to understand what exactly is happening and how this material works behind the scenes. I would like to know how to deal with this problem without using BackgroundWorker(as, for example, in .net 1.1), but I would also like to know if BackgroundWorkersuch problems are solved and how it is done.

Edit: I will take notes on your suggestions and try tomorrow and report back. At first I used volatile bool, I think I updated it to an automatic property and forgot about volatility. Can a worker thread search the cached value again and again? I don’t understand how I can have a fatal attack. An employee checks the flag because I managed to break it by setting a breakpoint on the fly. I always test the same data set, and most of the time it only cancels the penalty. The only thing that changes between tests is the moment when I click the "Cancel" button. So far I have only tested debugging starting with VS.

Edit 2: It turns out my problem is not related to my flag or anything I added. This is more of a WinForm problem. The program will receive a call ShowDialog(and ShowDialog is already disabled). I cannot drag the form, and it does not update by itself. The cancel button on it does not even work. Here is the call stack when I pause everything.

[Code externe]  
    Mrnf.Son.Commun.dll! Mrnf.Son.Commun.Messages.BarreProgressionBase.ShowDialog (System.Windows.Forms.IWin32Window fenetre = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}) Ligne 274 + 0xb octets C #
    Mrnf.Son.Commun.dll!Mrnf.Son.Commun.Controleurs.Utils.AttendreFinTraitement(System.Windows.Forms.Form parent = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}, Mrnf.Son.Commun.Messages.BarreProgressionBase progressionBase = {Mrnf.Son.Commun.Messages.BarreProgressionMessage}, System.Threading.Thread thread = {System.Threading.Thread}) Ligne 302 + 0xd octets    C#
    Mrnf.Son.Affaires.dll!Mrnf.Son.Affaires.Persisteurs.Echanges.LecteurDBFGeneriqueCollection.Importer(System.Windows.Forms.Form parent = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}) Ligne 95 + 0x1d octets    C#
    Mrnf.Son.Affaires.dll!Mrnf.Son.Affaires.Persisteurs.Echanges.PersisteurModeleEchanges.Importer(Mrnf.Son.Affaires.Entites.Echanges.ModeleEchanges unModele = {Mrnf.Son.Presentation.Windows.Controleurs.Echanges.ModeleEchanges.ModeleEchangesGenerique}, System.Windows.Forms.Form formParent = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}) Ligne 1880 + 0xd octets  C#
    Mrnf.Son.Affaires.dll!Mrnf.Son.Affaires.Entites.Echanges.ModeleEchanges.Importer(System.Windows.Forms.Form formParent = {Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm}) Ligne 875 + 0x18 octets  C#
    Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm.EffectuerImport(Mrnf.Son.Affaires.Entites.Echanges.IModeleEchanges modele = {Mrnf.Son.Presentation.Windows.Controleurs.Echanges.ModeleEchanges.ModeleEchangesGenerique}) Ligne 1429 + 0xc octets  C#
    Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm._terminerBtn_Click(object sender = {Text = Impossible d'évaluer l'expression, car un frame natif se trouve en haut de la pile des appels.}, System.EventArgs e = {System.EventArgs}) Ligne 1334 + 0x1d octets C#
[Code externe]  
    Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.UI.Echanges.AssistantForm.WndProc(ref System.Windows.Forms.Message m = {System.Windows.Forms.Message}) Ligne 1133 + 0xb octets C#
[Code externe]  
    Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.Controleurs.Sondages.ActionsSondages.OnImporterSysExt() Ligne 1362 + 0x1f octets    C#
    Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.UI.Sondages.UEExploitationVue._mniImporterSysExt_Click(object sender = {System.Windows.Forms.ToolStripMenuItem}, System.EventArgs e = {System.EventArgs}) Ligne 820 + 0x12 octets   C#
[Code externe]  
    Mrnf.Son.Presentation.Windows.exe!Mrnf.Son.Presentation.Windows.Program.Main() Ligne 148 + 0x8 octets   C#
[Code externe]  

3: null ShowDialog, ( , , ). .

+5
4

, , , .

WaitHandles Thread.Join()/Thread.Abort(), .

private readonly ManualResetEvent _ExitThreadsEvent = new ManualResetEvent(false);
private Thread _MyThread;

public void Stop()
{
    _ExitThreadsEvent.Set();

    if (_MyThread != null)
    {
        if (!_MyThread.Join(5000))
        {
            _MyThread.Abort();
        }

        _MyThread = null;
    }
}

private void MyThread()
{
    if (!_ExitThreadsEvent.WaitOne(1))
    {
        // Do some work...
    }

    if (!_ExitThreadsEvent.WaitOne(1))
    {
        // Do some more work...
    }
}

, .

+1

BackgroundWorker , , . , :

  • , , ( , , )

; :

  • (, Invoke , )
  • COM ( ), - ,

, ? , , , , , - - , , , .

+4

Application.DoEvents - , . .

" ", , " ". ? ? -? - ? , . , , , . .

+2

. , , Debug + Break All. Debug + Windows + Threads . , , , , .

, volatile. JIT , . , Release . Tools + Attach to Process , Break All.

ManualResetEvent, WaitOne (0).

+2

All Articles