Excel interop COM exception lors de l'exécution en arrière-plan
Je suis en train de faire appliquer des styles de cellules dans mon classeur. Et je veux le faire dans le thread d'arrière-plan, donc mon interface graphique peut rester sensible. Ce travail devrait prendre que quelques secondes, et si je clique sur certains aléatoire de cellules dans mon document, je vais devenir une exception. Voici mon code:
public void ApplyStyles()
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += DoWork;
bw.RunWorkerAsync();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
try
{
foreach (ICell xcell in cells)
{
Microsoft.Office.Interop.Excel.Range cell = cellUtility.GetCell(xcell);
if (styles.ContainsKey(styleIds[xcell.Style]))
{
Style s = styles[xcell.Style];
cell.Style = s;
}
}
}
catch (Exception ex)
{
if (Logger.IsErrorEnabled)
{
Logger.Error(ex.ToString());
}
messageBox.ShowErrorMessage(localizationMessages.ApplyingErrorText, localizationMessages.ApplyingErrorCaption);
}
}
Lorsqu'une exception se produit, c'est le message que je reçois;
System.Runtime.InteropServices.COMException (0x800AC472): Exception from HRESULT: 0x800AC472
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at Microsoft.Office.Interop.Excel.Range.set_Style(Object value)
at ABZ.ReportFactory.OfficeAddin.Excel.BatchLinking.BackgroundStyleApplier.DoWork() in C:\ABZ\ABZ ReportFactory Office Addin\ABZ.ReportFactory.OfficeAddin.Excel\BatchLinking\BackgroundStyleApplier.cs:line 86
Est-il possible de faire ce style de l'application de l'opération dans le thread d'arrière-plan? Et comment dois je faire?
Deuxième problème que j'ai est que, bien que ce style d'application est en cours d'exécution en arrière-plan de mon curseur est en constante évolution de l'état de l'agitation régulière jusqu'à ce que cette opération est terminée. Je voudrais curseur à la normale. L'utilisateur est totalement ignorant de cette opération en arrière-plan.
cheers,
Vladimir
- myomron.com/index.php?action=kb&article=1324
- Si l'Objet Excel est visible, bien que cela se déroule?
Vous devez vous connecter pour publier un commentaire.
Vous devez être sûr que vous obtenez la racine de l'Application Excel de l'objet, et à partir de là, la Plage, le fil où le travail est effectué. Excel objets COM vivons tous dans un Single-Threaded Apartment (STA) vous ne pouvez pas les utiliser à partir d'un autre thread.
Vous n'avez pas de montrer comment "cellUtility.GetCell" obtient réellement la Gamme, mais le problème probable est que vous utilisez un objet de l'Application qui a d'abord été récupérées à partir d'un autre thread.
Faire ce genre de travail sur un "thread d'arrière-plan, de sorte que votre interface utilisateur peut rester sensible" est problématique - tous les travaux dans Excel finit par se produit sur les principales Excel fil, depuis Excel est (essentiellement) single-threaded.
Il y a quelques façons de procéder:
Souvent, vous verrez que l'arrêt ScreenUpdating et de Calcul de réglage Manuel vous permet de faire le travail de montage beaucoup plus rapide, alors vous n'avez pas besoin d'autres threads ou quoi que ce soit.
Exécuter votre travail sur le thread principal, mais le casser en petits morceaux, puis de planifier le prochain morceau à faire après céder à Excel, vous pouvez créer un Windows.Les formulaires.Minuterie ou si vous pouvez exécuter une macro Excel utiliser l'Application.OnTime le calendrier de la prochaine pièce de travail.
Si vous voulez faire le travail à partir d'un autre thread, vous devez obtenir l'Application de l'objet et de la poursuite de l'objet COM sur ce thread. Il peut être difficile d'obtenir la bonne Application Excel exemple, mais Andrew Whitechapel décrit une approac ici: http://blogs.officezealot.com/whitechapel/archive/2005/04/10/4514.aspx. Cependant, vous devrez toujours vérifier les erreurs sur chaque appel COM partir d'un autre thread, depuis Excel peut être occupé et refuse tout appel COM à partir d'un autre thread à tout moment (notamment si vos utilisateurs sont en interaction avec le responsive GUI'. Vous avez besoin de vérifier au moins pour COMExceptions avec les erreurs - chaque appel COM pouvez jeter un de ces:
Excel-l'ADN (Excel /.NET de l'intégration de la bibliothèque que je développe) donne accès à un objet d'Application sur le fil vous sont en cours d'exécution en appelant ExcelDnaUtil.Application. Mais je continue de recommander le déplacement de toutes les interactions avec le modèle objet Excel pour les principaux Excel fil, peut-être l'aide d'un appel à Candidature.Exécuter pour exécuter dire à Excel pour exécuter une macro. L'Application.Exécuter devient alors un point unique où la COMException peut être vérifiée et de tentative d'appel à partir de votre thread d'arrière-plan.