Ist es möglich, einen event-handler auf einem anderen thread an den Aufrufer?

Können sagen, ich habe eine Komponente namens Tasking (das kann ich nicht ändern) was macht eine Methode "DoTask", die einige möglicherweise langwierigen Berechnungen und gibt das Ergebnis über eine Veranstaltung TaskCompleted. Normalerweise, das heißt in ein windows-Formular, das der Benutzer schließt nach bekommt Sie die Ergebnisse.

In meinem speziellen Szenario, das ich brauche zu assoziieren einige Daten (Datenbank-Datensatz) mit den zurückgegebenen Daten in TaskCompleted und verwenden Sie, um update-Datensatz in der Datenbank.

Hab ich untersuchte den Einsatz von AutoResetEvent zu Benachrichtigen, wenn das Ereignis behandelt wird. Das problem ist AutoResetEvent.WaitOne() blockiert und die event-handler wird nie aufgerufen. Normalerweise AutoResetEvents genannt werden, ist ein separater thread, also denke ich, das bedeutet, dass der event-handler ist auf dem gleichen thread die Methode aufruft.

Im wesentlichen, ich möchte einen asynchronen Aufruf, in dem die Ergebnisse zurückgegeben werden, über ein Ereignis, in einem synchronen Aufruf (ie call DoSyncTask aus einer anderen Klasse) blockiert bis das Ereignis behandelt wird und die Ergebnisse an einem Ort zugänglich zu beiden die event handler und die Methode, die die Methode aufgerufen, die den asynchronen Aufruf.

public class SyncTask
{
    TaskCompletedEventArgs data;
    AutoResetEvent taskDone;

public SyncTask()
{
    taskDone = new AutoResetEvent(false);
}

public string DoSyncTask(int latitude, int longitude)
{
    Task t = new Task();
    t.Completed = new TaskCompletedEventHandler(TaskCompleted);
    t.DoTask(latitude, longitude);
    taskDone.WaitOne(); //but something more like Application.DoEvents(); in WinForms.
    taskDone.Reset();
    return data.Street;
}

private void TaskCompleted(object sender, TaskCompletedEventArgs e)
{
    data = e;
    taskDone.Set(); //or some other mechanism to signal to DoSyncTask that the work is complete.
}
}

In a Windows App the following works correctly.

public class SyncTask
{
    TaskCompletedEventArgs data;

public SyncTask()
{
    taskDone = new AutoResetEvent(false);
}

public string DoSyncTask(int latitude, int longitude)
{
    Task t = new Task();
    t.Completed = new TaskCompletedEventHandler(TaskCompleted);
    t.DoTask(latitude, longitude);
    while (data == null) Application.DoEvents();

    return data.Street;
}

private void TaskCompleted(object sender, TaskCompletedEventArgs e)
{
    data = e;
}
}

Brauche ich nur, um zu replizieren, dass das Verhalten in einem Fenster-service, wo die Anwendung.Führen Sie nicht aufgerufen und die Datei ApplicationContext Objekt ist nicht verfügbar.

InformationsquelleAutor Rob Gray | 2009-01-28
Schreibe einen Kommentar