Der erste Aufruf von Search ruft DoEvents auf, welches bei einem weiteren Tastendruck wiederum StartSearch aufruft. Das springt in den else-Teil und wartet auf das Ende des ersten Aufrufs. Auf das Ende einer Methode, die weiter unten auf dem Callstack liegt, kann man im gleichen Thread allerdings lange warten
.
Code:
StartSearch()
-> DoEvents()
--> Search()
---> while (isSearching) ...
-> isSearching = false;
Mit etwas Umstrukturieren (genauer: Durch Iteratoren Coroutines simulieren...
) könnte man das Problem leicht lösen, aber wenn es deiner Anwendung nützt, würde ich direkt zu asynchroner Verarbeitung greifen.
Mit der TPL von .NET 4.0 gar kein Problem
... bis dahin sollte es aber auch so funktionieren:
Code:
object currentToken;
public void StartSearch()
{
var token = new object();
this.currentToken = token;
ThreadPool.QueueUserWorkItem(delegate {
var result = Search(...);
// In den UI-Thread wechseln
SynchronizationContext.Current.Send(delegate {
if (token == currentToken) // Ergebnis verwerfen, wenn schon die nächste Anfrage gestartet wurde
this.OnSearchCompleted(result);
}, null);
});
}
Ob das design-technisch optimal ist, will ich gerade lieber nicht beurteilen, denn über Design in Verbindung mit asynchronem Code musste ich mir bis jetzt noch nie Gedanken machen. Außerdem bin ich davon ausgegangen, dass deine Suchanfragen nicht so teuer sind, dass laufende Anfragen unbedingt abgebrochen werden müssen, wenn die nächste gestartet ist.