Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8550093
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T13:52:20+00:00 2026-06-11T13:52:20+00:00

Notice : I do not control the UI code. Only the class PeriodicalThing code.

  • 0

Notice: I do not control the UI code. Only the class PeriodicalThing code.


Consider this scenario:

The UI thread is happily doing UI stuff, while there is another background thread which periodically raises events. The events are subscribed to by some UI, which means the event handlers generally have to use Invoke.

What I need is a way to perform the clean up operation (cleaning up means stopping the background thread, basically) in safe manner, that guarantees:

  1. User-defined code (i.e. event handler code) is not asynchronously aborted in the middle of execution
  2. There are no more periodical operations executed or executing after the clean up function has returned
  3. No more event handlers will be executed or executing after the clean up function has returned

I came up with something, but there is a deadlock. The deadlock is basically an error in the user-defined code, where the usage of BeginInvoke could have fixed the problem, but a straight out deadlock in case of a non-trivial programming error isn’t the way to go.
Also note that BeginInvoke only happens to work in the FormClosing scenario because the invocation list of a Form happens to be cleared after FormClosing; something that seems to be consistent but I haven’t found it documented yet.

If there is a solution, it’s apparently not obvious, but maybe I’m missing out a trick. I can’t believe noone has run into a similar problem before.

class PeriodicalThing
{
    bool abort = false;
    Thread PeriodicalThread;
    ...
    PeriodicalThreadProc()
    {
        while (!this.abort)
        {
            DoStuff();
            OnThingsHappened(new EventArgs(...));
        }
    }

    public event EventHandler<EventArgs> ThingsHappened;
    protected virtual void OnThingsHappaned(EventArgs e)
    {
        // update -- oversight by me - see Henk Holterman's answer
        var handler = this.ThingsHappened;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    public void CleanUp()
    {
        this.abort = true;
        // ui thread will deadlock here
        this.PeriodicalThread.Join();
    }
}

...

// user-defined code; consider this immutable
class Form1 : Form
{
    .ctor()
    {
        ...
        this.PeriodicalThing.ThingsHappened += this.ThingsHappenedHandler
    }

    private void ThingsHappenedHandler(object sender, EventArgs e)
    {
        if (this.InvokeRequired) // actually always true
        {
            // periodical thread will deadlock here
            this.Invoke(
                new Action<object, EventArgs>(this.ThingsHappenedHandler), sender, e)
                );
            return;
        }
        this.listBox1.Items.Add("things happened");
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        this.PeriodicalThing.CleanUp();
    }
}

When the UI thread is shutting down due to an event such as FormClosing, which happened on the UI thread, then it will trigger the clean up. When the background thread issues an Invoke at this time, the Invoke has to block until the UI thread is finished with its current event handler (which triggered the clean up in the first place). Also, the clean up operation needs to wait for the background thread (and thus the current Invoke) to terminate, causing a deadlock.


The optimal solution would be to interrupt the UI thread at Thread.Join() and let all the waiting Invokes execute, and then going back to Thread.Join(). But that seems impossible to me with C#. Maybe someone has a crazy idea how I could use some helper threads to move the clean up method away from the UI thread, but I don’t know how I would do that.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T13:52:22+00:00Added an answer on June 11, 2026 at 1:52 pm

    The problem is here

    public void CleanUp()
    {
        this.abort = true;
        // ui thread will deadlock here
        this.PeriodicalThread.Join();  // just delete this
    }
    

    The Join() will block (!) the calling thread. And that in turn blocks all Invoke actions.

    The other part of this coin is

    {
      if (this.InvokeRequired) // actually always true
        {
            // periodical thread will deadlock here
        //    this.Invoke(
            this.BeginInvoke(            // doesn't wait so it doesn't block
                new Action<object, EventArgs>(this.ThingsHappenedHandler), sender, e)
                );
            return;
        }
        this.listBox1.Items.Add("things happened");
     }
    

    BeginInvoke is an improvement over Invoke anyway, as long as you only return void and do not overload the MessageLoop.

    But do get rid of the Join(). It has no use.

    Edit, since some parts are not under your control:

    The following is indeed the answer and it’s possible:

    to interrupt the UI thread at Thread.Join() and let all the waiting Invokes execute, and then going back to Thread.Join()

    public void CleanUp()
    {
        this.abort = true;
     
        while (! this.PeriodicalThread.Join(20)) 
        { 
           Application.DoEvents(); 
        }
    }
    

    This won’t deadlock but there are issues with using Application.DoEvents(). You’ll have to check what happens in all other events (FormClosing) and that’s not under your control too…
    It’ll probably work but some rigorous testing is called for.


    Since you are mixing threads and events, use this pattern:

    protected virtual void OnThingsHappaned(EventArgs e)
    {
        var handler = ThingsHappened;
    
        if (handler  != null)
        {
            handler (this, e);
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Consider this simple python code, which demonstrates a very simple version control design for
Yesterday I updated to firefox 13 and I notice that this property is not
I notice that NetBeans is warning me about using Thread.sleep() in a while loop
Bean is not marked to be in session scope still I notice the below
I notice that the character/symbol '`' and '@' is not used as an operator
I've notice django admin UI does not allow use name with characters that are
I'm reading PEP 8 and notice that it does not say anything on maximum
I visited Avis.com, and I notice the web pages have *.ac extension. Not familiar
I read here about std::auto_ptr<>::operator= Notice however that the left-hand side object is not
While designing a new WPF application I noticed exceptions not being thrown during data

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.