Je développe actuellement une application qui fait appel à des tâches asynchrones et des tâches de fond.
Dans mon application, je souhaite afficher des photos les unes après les autres.
Au niveau du chargement et de l'affichage, les étapes sont les suivantes :
Affichage d'un message de chargement
Téléchargement et mise en "cache" de 5 photos
Suppression du message de chargement
Affichage de la première photo
Demande d'affichage de la seconde photo
Téléchargement et mise en "cache" en arrière plan d'une 6ème photo
Affichage de la deuxième photo
Les étapes 4 à 7 se répètent alors jusqu'à épuisement des photos.
Pour les étapes 1 à 3, je n'ai aucun soucis. J'utilise les mots clefs async/await pour attendre la fin de mon téléchargement asynchrone.
J'ai cependant un problème avec l'étape 6. En effet, dans cette étape, je ne souhaite pas attendre la fin de mon téléchargement. Cette étape se fait en arrière plan. Je me suis donc tourné vers un BackgroundWorker.
Le problème est qu'au moment de lancer mon BackgroundWorker, j'ai une erreur. Voici le Message et le StackTrace :
Une exception de première chance de type 'System.UnauthorizedAccessException' s'est produite dans System.Windows.ni.dll
Une exception de type 'System.UnauthorizedAccessException' s'est produite dans System.Windows.ni.dll et n'a pas été traitée avant une limite managée/native
at MS.Internal.XcpImports.CheckThread()
at System.Windows.DependencyObject..ctor(UInt32 nativeTypeIndex, IntPtr constructDO)
at System.Windows.Media.Imaging.BitmapImage..ctor()
at myService.<GetAsyncRequestImage>d__5.MoveNext()
Invalid cross-thread access.
La méthode SelectAndDownloadAnEvent de mon objet :
public async Task SelectAndDownloadEvents()
{
return myService.GetAsyncRequestImage(uri);
}
Et finalement, la méthode qui pose problème GetAsyncRequestImage :
public static BitmapImage GetAsyncRequestImage(Uri uri)
{
try
{
var image = new BitmapImage();
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
var request = (HttpWebRequest) WebRequest.Create(uri);
request.BeginGetResponse(result =>
{
using (var sr = request.EndGetResponse(result))
{
image.SetSource(sr.GetResponseStream());
}
}, null);
});
return image;
}
catch (Exception)
{
return null;
}
}
Bien évidemment il ne s'agit que d'extraits de code. Par conséquent, certains mots clefs comme async ne sont pas exploités dans ce cas mais peuvent l'être dans d'autres. J'ai donc laissé les signatures de mes fonctions en l'état.
Je ne comprends pas trop l'origine du problème. En effet, comme lu un peu partout sur internet, j'ai ajouté l'encapsulation dans le dispatcher qui dans la théorie mon problème mais sans succès.
J'ai également tenté d'encapsuler le contenu de ma méthode dans un lock, mais une fois de plus sans succès.
J'ai du nouveau. Il semblerait que le constructeur d'un BitmapImage doit forcément être appelé dans le thread de l'UI.
J'ai donc modifié ma fonction de la façon suivante :
BitmapImage image = null;
AutoResetEvent bitmapInitialization = new AutoResetEvent(false);
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
image = new BitmapImage();
var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.BeginGetResponse(result =>
{
var response = request.EndGetResponse(result);
using (var stream = response.GetResponseStream())
{
image.SetSource(stream);
bitmapInitialization.Set();
}
}, null);
});
bitmapInitialization.WaitOne();
return image;
Mais j'ai toujours une erreur sur la ligne image.SetSource(stream);
Une exception de type 'System.IO.FileNotFoundException' s'est produite dans mscorlib.ni.dll et n'a pas été traitée avant une limite managée/native
Une exception de première chance de type 'System.UnauthorizedAccessException' s'est produite dans System.Windows.ni.dll
Une exception de type 'System.UnauthorizedAccessException' s'est produite dans System.Windows.ni.dll mais n'a pas été gérée dans le code utilisateur
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Mon site - Mon livre sur le XML - Mon blog
Mon site - Mon livre sur le XML - Mon blog