Hallo,
ich Programmiere gerade ein Outlook VSOT Addin, das Mails anhand ihres Betreffs in verschiedene öffentliche Ordner in Outlook einordnet.
Da die öffentlichen Ordner nicht besonders strukturiert sind, mache ich eine rekursive Suche nach dem passenden Ordner:
Nun friert dadurch natürlich erstmal die Outlook-GUI ein. Die öffentlichen Ordner sind je nach Netzwerkverbindung ziemlich lahm. Auch, wenn ich im Outlook auf einen klicke, dauert es ca. 3s, bis dieser Ordner aufgeht. Die gesamte Suche dauert bei einem Ordner der ziemlich tief in der Struktur liegt und entsprechend spät gefunden wird, etwa 90s. Das ist halt inakzeptabel die GUI für 90s einzufrieren.
Ich habe nun versucht den ganzen Archiviervorgang in einem eigenen Thread auszufuehren, indem ich da, wo der Vorgang gestartet wird (beim Klick auf einen Button im Ribbon) das mache:
ArchiveSelectedMails() startet dann spaeter auch die Methode searchForFolderByName(). Das funktioniert auch insofern, dass die GUI wieder reagiert, allerdings so ruckelig, dass man eigentlich auch nicht arbeiten kann.
Als nächsten habe ich gelesen, dass es DoEvents() gibt. Das hat ja anscheinen auch seinen Ruf, aber Versuch macht kluch. Hab ich so ausprobiert:
Nun ist es so, dass ich keine Schleife habe, dessen häufige Ausführung vieler kleiner schneller Befehle den Thread blockieren wuerden, sondern die Anweisung " InStr(LCase(Folder.Name), LCase(searchedFolderName))" ist einfach sehr langsam (300-500ms laut Visual Studio, manchmal sind aber auch Zugriffe dabei, die mehrere Sekunden dauern.) was an dem Netzwerkzugriff liegt. Das heist der macht jetzt immer eine Anweisung die eine halbe Sekunde dauert und dann ein DoEvents(). Entsprechend ruckelig ist die GUI auch.
Bei dem Thread vermute ich eine ganz ähnliche Problematik. Der Thread wird anscheinend nicht wirklich Parallel mit dem Main (GUI)-Thread ausgeführt, sondern es wird immer mal ein bisschen was in einem Thread gemacht und dann in dem Anderen. Wenn der Ordnersuche-Thread nun eine Anweisung hat, die lange dauert, ist der GUI-Thread für diese Zeit auch blockiert.
Ich denke, wenn ich es hinkriegen würde, dass der Suche-Thread auf einem separaten Prozessor ausgeführt wird, also wirklich parallel zu dem Main-Thread, dann würde es auch gehen. Nur wie geht das?
Darum den Suche-Thread zu blockieren, damit der User das nicht zweimal drücken kann, kümmer ich mich, wenn es funktioniert.
Gruesse
Schievel
ich Programmiere gerade ein Outlook VSOT Addin, das Mails anhand ihres Betreffs in verschiedene öffentliche Ordner in Outlook einordnet.
Da die öffentlichen Ordner nicht besonders strukturiert sind, mache ich eine rekursive Suche nach dem passenden Ordner:
VB.NET-Quellcode
- Private Function searchForFolderByName(ByVal startFolder As Object, searchedFolderName As String, recursive As Boolean) As Folder
- ' sucht in einem uebergebenen Startfolder nach einem Unterordner mit dem uebergebenen Namen. Bei recursive = true werden auch Unterordner bis in alle Ebenen mitdurchsucht
- ' sucht NICHT case sensitive
- Dim Folder As Folder
- For Each Folder In startFolder.Folders
- If InStr(LCase(Folder.Name), LCase(searchedFolderName)) Then
- searchForFolderByName = Folder
- Exit Function
- Exit For
- End If
- If recursive Then
- searchForFolderByName = searchForFolderByName(Folder, searchedFolderName, True)
- If Not searchForFolderByName Is Nothing Then
- If InStr(LCase(searchForFolderByName.Name), LCase(searchedFolderName)) Then
- Exit Function
- Exit For
- End If
- End If
- End If
- Next
- Return Nothing
- End Function
Nun friert dadurch natürlich erstmal die Outlook-GUI ein. Die öffentlichen Ordner sind je nach Netzwerkverbindung ziemlich lahm. Auch, wenn ich im Outlook auf einen klicke, dauert es ca. 3s, bis dieser Ordner aufgeht. Die gesamte Suche dauert bei einem Ordner der ziemlich tief in der Struktur liegt und entsprechend spät gefunden wird, etwa 90s. Das ist halt inakzeptabel die GUI für 90s einzufrieren.
Ich habe nun versucht den ganzen Archiviervorgang in einem eigenen Thread auszufuehren, indem ich da, wo der Vorgang gestartet wird (beim Klick auf einen Button im Ribbon) das mache:
ArchiveSelectedMails() startet dann spaeter auch die Methode searchForFolderByName(). Das funktioniert auch insofern, dass die GUI wieder reagiert, allerdings so ruckelig, dass man eigentlich auch nicht arbeiten kann.
Als nächsten habe ich gelesen, dass es DoEvents() gibt. Das hat ja anscheinen auch seinen Ruf, aber Versuch macht kluch. Hab ich so ausprobiert:
VB.NET-Quellcode
- Private Function searchForFolderByName(ByVal startFolder As Object, searchedFolderName As String, recursive As Boolean) As Folder
- ' sucht in einem uebergebenen Startfolder nach einem Unterordner mit dem uebergebenen Namen. Bei recursive = true werden auch Unterordner bis in alle Ebenen mitdurchsucht
- ' sucht NICHT case sensitive
- Dim Folder As Folder
- For Each Folder In startFolder.Folders
- If InStr(LCase(Folder.Name), LCase(searchedFolderName)) Then
- searchForFolderByName = Folder
- Exit Function
- Exit For
- End If
- If recursive Then
- searchForFolderByName = searchForFolderByName(Folder, searchedFolderName, True)
- If Not searchForFolderByName Is Nothing Then
- If InStr(LCase(searchForFolderByName.Name), LCase(searchedFolderName)) Then
- Exit Function
- Exit For
- End If
- End If
- End If
- If GetInputState() <> 0 Then
- System.Windows.Forms.Application.DoEvents()
- End If
- Next
- Return Nothing
- End Function
Nun ist es so, dass ich keine Schleife habe, dessen häufige Ausführung vieler kleiner schneller Befehle den Thread blockieren wuerden, sondern die Anweisung " InStr(LCase(Folder.Name), LCase(searchedFolderName))" ist einfach sehr langsam (300-500ms laut Visual Studio, manchmal sind aber auch Zugriffe dabei, die mehrere Sekunden dauern.) was an dem Netzwerkzugriff liegt. Das heist der macht jetzt immer eine Anweisung die eine halbe Sekunde dauert und dann ein DoEvents(). Entsprechend ruckelig ist die GUI auch.
Bei dem Thread vermute ich eine ganz ähnliche Problematik. Der Thread wird anscheinend nicht wirklich Parallel mit dem Main (GUI)-Thread ausgeführt, sondern es wird immer mal ein bisschen was in einem Thread gemacht und dann in dem Anderen. Wenn der Ordnersuche-Thread nun eine Anweisung hat, die lange dauert, ist der GUI-Thread für diese Zeit auch blockiert.
Ich denke, wenn ich es hinkriegen würde, dass der Suche-Thread auf einem separaten Prozessor ausgeführt wird, also wirklich parallel zu dem Main-Thread, dann würde es auch gehen. Nur wie geht das?
Darum den Suche-Thread zu blockieren, damit der User das nicht zweimal drücken kann, kümmer ich mich, wenn es funktioniert.
Gruesse
Schievel