Reputation: 975
C# windows forms VS 2013 OS:Win7
I am having an interesting problem where invokeRequired is true but when I call beginInvoke() it never executes and the window never closes.
However when I remove beingInvoke() altogether the window closes ok.
public void CloseMyForm()
{
//if I remove this if block altogether including beingInvoke() the window closes ok
if ( !this.IsDisposed && this.InvokeRequired && this.IsHandleCreated )
{
log("callin begininvoke()"); //this is logged correctly
this.BeginInvoke((MethodInvoker)delegate() { CloseMyForm(); });
return;
}
log("outside of begin invoke"); //this is never logged
this.Close();
}
CloseMyForm is called by a separate thread which is created like this at the startup. Please note this is not the main window but a separate window open from the main form.
Thread connectThread = new Thread(new ThreadStart(CheckWhenToCloseMyForm));
public void CheckWhenToCloseMyForm()
{
while (true)
{
CallSomeFunc();
CallSomeFunc1();
if (allconditionsmet)
{
System.Threading.Thread.Sleep(1000);
CloseMyForm();
break;
}
}
}
Upvotes: 1
Views: 1234
Reputation: 24525
Okay, now that you have provided this snippet I understand the issue.
Thread connectThread = new Thread(new ThreadStart(CheckWhenToCloseMyForm));
public void CheckWhenToCloseMyForm()
{
while (true)
{
CallSomeFunc();
CallSomeFunc1();
if (allconditionsmet)
{
System.Threading.Thread.Sleep(1000);
CloseMyForm()
}
}
}
In your while
loop you need to break
or return
after you invoke CloseMyForm
. That's it...very simple. You can use either BeginInvoke
or Invoke
.
Upvotes: 0
Reputation: 24525
The BeginInvoke
is made available via the base Control
class.
Executes a delegate asynchronously on the thread that the control's underlying handle was created on
If the InvokedRequired
property is actually true, that means "the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on".
It looks like you're incorrectly calling BeginInvoke
, you should try calling Invoke
instead.
Executes the specified delegate on the thread that owns the control's underlying window handle
public void CloseMyForm()
{
if (!this.IsDisposed && this.InvokeRequired && this.IsHandleCreated)
{
log("calling invoke()");
this.Invoke((MethodInvoker)delegate() { CloseMyForm(); });
}
else
{
log("outside of invoke"); // this is never logged
this.Close();
}
}
Check out this neat little extension method that could help simplify this. With this you could write your close method like this instead.
public void CloseMyForm()
{
this.ThreadSafeInvoke(() => this.Close());
}
Upvotes: 2