Cross Thread Calls
- From: james@xxxxxxxxxxxxxxxxxxxxxx
- Date: 22 Feb 2006 05:42:36 -0800
Hi
I've recently upgraded to Microsoft Visual Studio 2005. I am having
difficulty with cross thread calls. I would rather not succumb to the
easy route of setting Control.CheckForIllegalCrossThreadCalls = false.
I have designed a control that sits on a web form and is a container
for a Flash.ocx control. It has two main functions, first to preload
the flash viewer with a flash clip from a file, the second to play the
clip.
In previous versions of the code I have user threads and state changes
to preload the clip, returning control to my main thread whilst it is
loading. The play function also runs within a separate thread, though
this is not absolutely necessary.
I have now spent a good few days attempting to rewrite the code to
prevent the cross thread calls exception from being thrown with no
success. I have mainly tried using the Invoke method.
The important parts of the code are as below. It fails with a cross
thread call after the fFlashViewer.Play(); line has been called.
public bool LoadAsset(TasXmlAssetFlash asset) {
// Return false by default.
bool success = false;
try {
// Set the asset.
fAsset = asset;
// Start the thread load asset.
if (null == fThreadLoadAsset) {
fThreadLoadAsset = new Thread(new ThreadStart(RunLoadAsset));
fThreadLoadAsset.Name = THREAD_NAME;
fThreadLoadAsset.Start();
// Return true.
success = true;
}
}
catch (Exception exception) {
// Report the error.
TutDebug.Fail(exception);
}
return success;
}
public bool PlayAsset() {
// Return false by default.
bool success = false;
try {
// Finish the thread load asset.
if (null != fThreadLoadAsset) {
if (fThreadLoadAsset.IsAlive)
fThreadLoadAsset.Join();
}
// Play the asset.
if ((STATUS.LOADED == fStatus) && (null == fThreadPlayAsset)) {
fThreadPlayAsset = new Thread(new ThreadStart(RunPlayAsset));
fThreadPlayAsset.Name = THREAD_NAME;
fThreadPlayAsset.Start();
fThreadPlayAsset.Join();
}
// Return the success.
success = (STATUS.PLAYED == fStatus);
}
catch (Exception exception) {
// Report the error.
TutDebug.Fail(exception);
}
finally {
// Clean up.
fThreadLoadAsset = null;
fThreadPlayAsset = null;
}
return success;
}
private void RunLoadAsset() {
try {
// Load the flash.
if (null != fAsset) {
// Update the status.
fStatus = STATUS.LOADING;
this.Invoke(new MethodInvoker(delegate() {
fFlashViewer.LoadMovie(0, Path.Combine(
TutSystemIniFile.GetAssetDirPath(), fAsset.fFileName));
while (0 == fFlashViewer.ReadyState) { }
fFlashViewer.Rewind();
}));
// Update the status.
fStatus = STATUS.LOADED;
}
}
catch (ThreadAbortException) {
Thread.ResetAbort();
}
catch (Exception exception) {
// Report the error.
TutDebug.Fail(exception);
// Update the status.
fStatus = STATUS.ERROR;
}
}
private void RunPlayAsset() {
try {
// Play the flash.
if (null != fAsset) {
// Update the status.
fStatus = STATUS.PLAYING;
this.Invoke(new MethodInvoker(delegate() {
fFlashViewer.Loop = fAsset.Loop;
fFlashViewer.Play();
}));
this.Visible = true;
if (TasXmlAsset.PLAY.DURATION == fAsset.Play) {
DateTime end = (DateTime.Now).AddSeconds(fAsset.fPlayDuration);
while (DateTime.Now < end) {
// Sleep.
try {
Thread.Sleep(SLEEP_TIME);
}
catch (ThreadInterruptedException) { }
}
}
// Update the status.
fStatus = STATUS.PLAYED;
}
}
catch (ThreadAbortException) {
Thread.ResetAbort();
}
catch (Exception exception) {
// Report the error.
TutDebug.Fail(exception);
// Update the status.
fStatus = STATUS.ERROR;
}
finally {
try {
this.Visible = false;
this.Invoke(new MethodInvoker(delegate() {
fFlashViewer.Stop();
}));
}
catch (Exception) { }
}
}
I would be extremely grateful if anyone can help...
James Dutton
.
- Prev by Date: Re: How to contrain the interfaces of types passed to a constructor
- Next by Date: Serialize as debugging
- Previous by thread: Reduce the number og colors in an image?
- Next by thread: Serialize as debugging
- Index(es):
Relevant Pages
|