2011-05-09 2 views
0

Salut J'ai écrit ce petit échantillon de AddIn vous montrer un problème de performance et comment l'éviterVSTO excel problème de performance objet

que quelqu'un peut me expliquer pourquoi et comment cela fonctionne? Il s'agit simplement d'une analyse d'un classeur Excel exécuté dans le processus Excel principal (0) et d'un fil aléatoire créé par la minuterie.

Merci!

Public Class ThisAddIn 

Dim a As System.Windows.Threading.Dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher() 
Dim t As New Threading.Thread(New Threading.ParameterizedThreadStart(AddressOf threadTest)) 
Dim tm As New System.Timers.Timer(20000) 
Delegate Sub TestHandler() 
Dim tt As TestHandler = AddressOf test 

Private Sub ThisAddIn_Startup() Handles Me.Startup 
    tm.AutoReset = True 
    tm.Start() 
    AddHandler tm.Elapsed, AddressOf threadTest 
End Sub 

Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown 

End Sub 

Public Sub test() 
    Dim appE As Excel.Application = Globals.ThisAddIn.Application 
    Dim wb As Excel.Workbook = appE.ActiveWorkbook 
    Dim ws As Excel.Worksheet = wb.ActiveSheet 
    Dim rng As Excel.Range = ws.Cells(1, 1) 

    Dim nbit As Integer = 10000 
    For i = 1 To nbit 
     rng.Value = i 
    Next 
End Sub 

Private Sub threadTest() 
    ' 800 ms 
    Dim o() As Object 
    a.Invoke(tt, o) 

    '12 seconds ! 
    test() 

End Sub 
End Class 
+0

Vous nous demandez de déterminer si votre complément fonctionne et pourquoi? Il semble que vous seriez le plus capable de le faire. – IAmTimCorey

+0

Je ne vois aucune analyse de la feuille de calcul qui se passe ici. Tout ce que je vois, c'est que vous essayez d'écrire un nombre de 1 à 10 000 à la cellule A1 dans une boucle forcée dans un appel fileté. – code4life

+0

Encore une chose à réaliser est que chaque fois que vous appelez rng.Value, c'est en fait un appel de fonction COM que vous faites. Dans VSTO, le meilleur moyen de réduire les frais généraux est de réduire le plus possible les appels de fonctions COM dans leur ensemble. – code4life

Répondre

1

Vous plongez dans le monde des modèles de filetage COM. C'est un bon début comme: http://msdn.microsoft.com/en-us/library/ms693344(VS.85).aspx.

Si le code s'exécute sur le thread principal Excel (que vous obtenez en configurant le Dispatcher), les appels COM ne sont pas marshalés entre threads différents. Comme vous avez beaucoup d'appels COM (chaque .Value compte pour un), les frais généraux s'ajoutent aux différences que vous voyez. L'une des raisons pour lesquelles le marshaling coûte cher dans ce contexte, c'est que les objets COM Excel s'exécutent dans un STA (single-threaded apartment), ce qui signifie qu'une boucle de messages est configurée (en fait une boucle de messages Windows) dans Excel pour sérialiser les appels COM. Chaque appel inter-appartement que vous effectuez entraîne un message en cours de publication dans cette boucle de message, qui est traitée sur le thread principal Excel.

Ainsi, les deux cas diffèrent en termes de performances en raison du marshaling COM inter-appartements. Il est remarquablement rapide, compte tenu de ce qui se passe dans les coulisses. Dans les deux cas, effectuer un appel unique pour définir la valeur .Value d'une plage étendue sur un tableau de valeurs sera beaucoup plus rapide. Et pour le plus rapide (millions de cellules par seconde) pour définir les données dans votre feuille Excel, voir ici: Fastest way to interface between live (unsaved) Excel data and C# objects.

+0

Merci pour votre réponse! – Avlin