Обычно OnDoSomethingCompleted () выполняется в потоке пользовательского интерфейса, то есть за кулисами что-то вызывает некоторый код, который (концептуально) выглядит примерно так:
Dispatcher.BeginInvoke(() => OnDoSomethingCompleted());
Это означает, что OnDoSomethingCompleted () не будет выполняться, пока поток пользовательского интерфейса не решит сотрудничать и запустить его. В большинстве случаев это нормально, но могут быть моменты, когда вы хотите, чтобы он работал быстрее. Основной подход заключается в использовании пула потоков для выполнения исходного вызова, что означает, что ответ будет обработан из того же пула потоков (не обязательно в одном и том же потоке). Если вы можете выполнить некоторую реальную обработку в этом методе возврата, а не просто автоматически перенаправить ее обратно в поток пользовательского интерфейса, это может несколько ускорить вашу обработку.
Томек (из команды MS WCF) дает хороший пример того, как это сделать здесь:
http://tomasz.janczuk.org/2009/08/improving-performance-of-concurrent-wcf.html
Я также понимаю, что контекст синхронизации для соединения WCF устанавливается при первом его открытии. Это означает, что независимо от того, в каком потоке сначала открывается соединение WCF, он обрабатывает все последующие вызовы. Так что в моем собственном коде я делаю что-то вроде этого:
// Spin up the connection on a new worker thread.
// According to Tomek, this will cause all WCF calls to be made from this thread.
ManualResetEvent resetEvent = new ManualResetEvent(false);
wcfWorkerThread = new Thread(new ThreadStart(() => InitializeNotificationClient(resetEvent)));
wcfWorkerThread.Name = "WcfWorkerThread";
wcfWorkerThread.Start();
resetEvent.WaitOne();
И тогда InitializeNotificationClient () выглядит примерно так:
private void InitializeNotificationClient(ManualResetEvent resetEvent = null)
{
try
{
notificationClient = GetRoomServiceClient();
notificationClient.OpenAsync(callback);
notificationClient.InnerChannel.Faulted += new EventHandler(Channel_Faulted);
notificationClient.InnerChannel.Closed += new EventHandler(Channel_Closed);
}
finally
{
// Tell the waiting thread that we're ready.
if (resetEvent != null)
{
resetEvent.Set();
}
}
}