Silverlight Download XAP in Background Thread

Nov 11, 2010 at 8:00 PM

I'm Developing an application that loads module XAPs via MEF using the DeploymentCatalog Class, what I want to do is have this process happen in a background worker thread, so it doesn't block the GUI up.

When I do this in a background worker thread I get an Error in the Downloaded Completed Event saying that there is a CrossAccess Thread Exception. Is there any one else out there having the same problem, and is there any one know of a solution to this problem.

 

Brian

 

 

 
Coordinator
Nov 11, 2010 at 9:20 PM

The DeploymentCatalog already does its downloading asynchronously, so the download won't block the UI thread.  Once the download completes the catalog would be created on the UI thread, but I wouldn't expect that to introduce a noticeable delay.  Were you having issues?

I'm not sure why you are getting the error though.  Can you post the code in your download completed event, as well as the full exception message and stack trace you get?

Thanks,
Daniel 

Nov 11, 2010 at 10:09 PM

Daniel Here is the Code I'm Using to Load the Modules

 First off the code to start the downloads

 

 

 

 

 

 

 

 

 

 

 

 

Uri hostUri = App.Current.Host.Source;

 

 

 

 

List<DeploymentCatalog> deploymentCatalogs = new List<DeploymentCatalog

>();

_totalNumberOfToModules = WebContext

.Current.User.UserModules.Count;

 

foreach (UserPermissableModule moduleName in WebContext.Current.User.UserModules)

{

 

 

Uri uri = new Uri(hostUri, string.Format("{0}.xap"

, moduleName.Name));

deploymentCatalogs.Add(new DeploymentCatalog

(uri));

}

 

 

CompositionHost

.Initialize(deploymentCatalogs.ToArray());

 

 

 

foreach (DeploymentCatalog deploymentCatalog in

deploymentCatalogs)

{

deploymentCatalog.DownloadCompleted += DownloadCompleted;

deploymentCatalog.DownloadAsync();

}

 

 

 

 

 



and now the completed method.

 

 

 

 

 

 

 

 

 

 

 

private void DownloadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)

{

 

 

if (e.Error == null

)

{

((ShellViewModel)((UserControl) Application

.Current.RootVisual).DataContext).BusyMessage = "Loaded Module "

+

System.IO.Path.GetFileName(((DeploymentCatalog

) e.UserState).Uri.LocalPath);

 

_modulesLoaded++;

 

 

if

if (_modulesLoaded == _totalNumberOfToModules)

{

 

 

CompositionInitializer.SatisfyImports(this);

}

}

 

 

else

{

 

 

 

 

throw new CommunicationException("Unable To Load Modules");

}

}

I know that the download is Async, I guess what is freezing up the GUI from updating the message is the fact that MEF is processing the Stream of the XAP in the GUI thread.

 

The Error Message is below when I load using a background thread

 

Invalid cross-thread access. 

 at MS.Internal.XcpImports.CheckThread()
   at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex, IntPtr constructDO)
   at System.Windows.AssemblyPart..ctor()
   at System.ComponentModel.Composition.Hosting.Package.GetDeploymentParts(StreamResourceInfo xapStreamInfo)
   at System.ComponentModel.Composition.Hosting.Package.LoadPackagedAssemblies(Stream packageStream)
   at System.ComponentModel.Composition.Hosting.DeploymentCatalog.HandleOpenReadCompleted(Object sender, OpenReadCompletedEventArgs e)

 

Brian

 

 

Coordinator
Nov 16, 2010 at 10:43 PM

Is the code you use to start the downloads running on a UI or background thread?  It needs to run on the UI thread, otherwise I believe the DownloadCompleted event won't be marshalled back to the UI thread.  The code in that event needs to run on the UI thread.  You can't call CompositionInitializer.SatisfyImports from a background thread, because the container isn't thread-safe, and because doing so will create UI objects if you have exported any UI objects, and those need to be created on the UI thread.

 

 

Jan 18, 2011 at 1:54 PM

BTW I've noticed the same problem - GUI is freezes during DeploymentCatalog.DownloadAsync....
I did some tests with big XAP parts (abt 0.5 GB) 

Another issue (may be related) that DownloadProgressChanged event called in very strange way. ProgressPercentage starts from 50-60%.