2011-05-09 29 views
0

嗨 我寫了這個小的AddIn樣本向您展示性能問題以及如何避免它VSTO Excel對象性能問題

有人能解釋我爲什麼,它是如何工作的?

它只是一個excel工作簿的解析,運行在主excel進程(0)和計時器創建的隨機線程中。

謝謝!

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

你問我們想知道你的加載項是否工作,爲什麼?看起來你會是最能做到這一點的人。 – IAmTimCorey 2011-05-09 14:51:20

+0

我在這裏看不到任何工作表的解析。我所看到的是,你正試圖在一個線程調用的for循環中寫入一個從1到10,000的數字到單元格A1。 – code4life 2011-05-09 15:01:35

+0

還有一件事要認識到,每次你調用rng.Value時,這實際上是一個你正在做的COM函數調用。在VSTO中,降低性能開銷的最佳方法是儘可能減少整體COM函數調用。 – code4life 2011-05-09 15:03:00

回答

1

您正在潛入COM線程模型的世界。這是一個很好的開始:http://msdn.microsoft.com/en-us/library/ms693344(VS.85).aspx

如果代碼在Excel主線程(通過設置Dispatcher實現)上運行,則COM調用不會跨不同線程編組。由於您有很多COM調用(每個.Value算作一個),開銷會增加您看到的差異。

在這種情況下編組成本高昂的原因之一是Excel COM對象在單線程單元(STA)中運行,這意味着有一個消息循環設置(實際上是一個Windows消息循環)在Excel中以序列化COM調用。每個跨公寓調用的結果都會將消息發佈到此消息循環中,這是在主Excel線程上處理的。

因此,由於COM跨公寓編組,所以這兩種情況的性能不同。這實際上非常快,考慮到幕後發生的事情。

在這兩種情況下,進行單個調用以將大範圍的.Value設置爲值數組將更快。對於將數據設置到Excel表格中的最快(每秒百萬個單元格)的方式,請參閱此處:Fastest way to interface between live (unsaved) Excel data and C# objects

+0

感謝您的回覆! – Avlin 2011-05-09 15:49:33