Cross Thread Calls

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



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

.



Relevant Pages

  • exception using wmic
    ... I get an exception when I try to execute any command using wmic. ... SUCCESS: CoCreateInstance(CLSID_XSLTemplate, NULL, CLSCTX_SERVER, ...
    (microsoft.public.win32.programmer.wmi)
  • Re: Removing else blocks
    ... > return success; ... throw an exception. ... In most of these cases I actually use an ASSERT macro to do the "throw ... I know Bjarne recommends using a template for ...
    (comp.lang.cpp)
  • Re: Oklahomas innovations
    ... anticipated its "innovations" but argues that they didn't "Change ... different kind - and that OK!'s *success* was the factor that changed that. ... furthering of those innovations made it impossible to go back to essentially ... "revolution" (the one main exception, of course, was ONE TOUCH OF VENUS ...
    (rec.arts.theatre.musicals)
  • Re: Handling exceptions
    ... I understand that failure will always be returned because of the ... What is the best practice to return a value if success or failure. ... Or should the exception be propagated to the calling method? ... void foo() throws FooException { ...
    (comp.lang.java.programmer)