This is in regards to the following error, which is generated seemingly at
random after closing out of a form with several buttons whose image
properties are set to looping animated GIFs:
"System.InvalidOperationException was unhandled
Message="Invoke or BeginInvoke cannot be called on a control until the
window handle has been created."
Source="System.Windows.Forms"
StackTrace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller,
Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.BeginInvoke(Delegate method, Object[]
args)
at System.Windows.Forms.ButtonBase.OnFrameChanged(Object o, EventArgs
e)
at System.Drawing.ImageAnimator.ImageInfo.OnFrameChanged(EventArgs e)
at System.Drawing.ImageAnimator.ImageInfo.set_Frame(Int32 value)
at System.Drawing.ImageAnimator.AnimateImages50ms()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()"
This is despite my code being single-threaded, and with no explicit calls to
any ImageAnimator routines.
I began troubleshooting by creating simple project with a single form and
button, whose Image property I again assigned a looping animated gif. Soon
into debugging, I experienced the same error, again when closing the form. It
was not reproducible however, even after a quick relaunch. Further tests
showed it had nothing to do either with the GIF being on a certain a frame,
nor with the program running for a certain amount of time.
Digging a little further, while debugging, I was able to verify, per the
error details, that a thread named "ImageAnimator" was indeed running in the
background, again without me explicitly instantiating it (somewhat at odds
with VS Documentation, whose example on the ImageAnimator class has you
manually updating the frames of a GIF, with no reference to threading). From
my observation, this thread is a background thread, but becomes the current
thread when the ImageAnimator.Animate procedure calls its EventHandler. Here
are its thread properties in the EventHandler:
base {System.Runtime.ConstrainedExecution.CriticalFinalizerObject}:
{System.Threading.Thread}
ApartmentState: MTA
CurrentCulture: {en-US}
CurrentUICulture: {en-US}
ExecutionContext: {System.Threading.ExecutionContext}
IsAlive: true
IsBackground: true
IsThreadPoolThread: false
ManagedThreadId: 11
Name: "ImageAnimator"
Priority: Normal
ThreadState: Background
As the form closes, however, the thread state will alternate between
"Background" and "Background, WaitSleepJoin" for no discernible reason. In
the form_closing event I also found that manually setting the button or
button image to null while the ImageAnimator thread was still running will
not reliably cause the error.
In which case, how do I continue troubleshooting a thread which I haven't
started, and which I have no direct access to? Would a Thread Join at the
form closing suffice? Here is my test code:
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
private Thread tempThread;
public Form1()
{
InitializeComponent();
button1.Paint += new PaintEventHandler(button1_Paint);
ImageAnimator.Animate(button1.Image, new
EventHandler(this.OnFrameChanged));
}
private void OnFrameChanged(object sender, EventArgs e)
{
tempThread = Thread.CurrentThread;
}
private void button1_Paint(object sender, PaintEventArgs e)
{
//This statement is unnecessary, ImageAnimator thread
automatically repaints images
//ImageAnimator.UpdateFrames();
}
private void Form1_FormClosing(object sender, EventArgs e)
{
Console.WriteLine("{0}: {1}", tempThread.Name,
tempThread.ThreadState);
}
static void Main()
{
Application.Run(new Form1());
}
}
}

Signature
Kenneth Lemieux
Project Engineer
Whelen Engineering Co., Inc.
Linda Liu [MSFT] - 26 Feb 2007 04:22 GMT
Hi Kenneth,
Based on my understanding, you have a button on a form, and the button's
Image property is set to a looping animated GIF. When you click the button,
the form is closed. The problem is that when you click the button to close
the form, an error occurs. If you set the button or button.Image to null in
the form's Closing event handler, the error disappears. If I'm off base,
please feel free to let me know.
I performed a test on this issue but didn't reproduce the problem. I create
a WinForm application project and add a button on the form. I set the Image
property of the button to a looping animated GIF and handle the Click event
of the button to close the form. When the program is run, I click the
button and the form is closed without any error.
I also performed a test based on your sampe code. I did see the thread
named 'ImageAnimator' becomes the current thread when the
ImageAnimator.Animate procedure calls its EventHandler, and the ThreadState
of the thread 'ImageAnimator' becomes 'Background, WaitSleepJoin' in the
form's Closing event handler.
I think the thread 'ImageAnimator' is created by the application
automatically and is a managed thread. When the form is closed, CLR calls
the Sleep method of the managed thread, so the ThreadState of the thread
'ImageAnimator' becomes 'Background, WaitSleepJoin'. Generally, we needn't
handle a managed thread directly that is created and started by CLR,
because CLR will take charge of it.
> somewhat at odds with VS Documentation, whose example on the
ImageAnimator class has you manually updating the frames of a GIF, with no
reference to threading
The MSDN code sample of ImageAnimator shows how to display a looping
animated GIF on a form. Form has only a property called 'BackgroundImage'.
When we set the BackgroundImage property to a looping animated GIF, the
background image of the form is still static. Because we needn't take care
of the background thread in this case, the MSDN sample has no reference to
threading.
If the problem is still not resolved, you may send me your sample project
that could just reproduce the problem. To get my actual email address,
remove 'online' from my displayed email address.
Sincerely,
Linda Liu
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
Linda Liu [MSFT] - 28 Feb 2007 11:52 GMT
Hi Kenneth,
How abou the problem now?
If the problem is still not resolved, please feel free to let me know.
Thank you for using our MSDN Managed Newsgroup Support Service!
Sincerely,
Linda Liu
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.
Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.