我同意,應該有一些比你目前的方法更容易。但是,除非我們可以使用T4模板來生成代理類,否則,除非你想推出自己的(不推薦IMO,YMMV),否則按照你已經嘗試過的方式來看,你認爲最好的方法就是拍攝。
我目前正在使用這兩種方法的混合。我已經將所有WCF調用包裝在一系列數據訪問類中,這些類將MS提供的不太有用的事件驅動模型轉換爲更簡單的回調方法。在這些數據訪問類中,我還使用一個靜態的PreProcessCall()方法來封裝每個調用,該方法處理增加未完成的調用計數器並將調用編組到後臺線程;我用靜態的PostProcessCall()方法封裝了每個返回調用,該方法遞減未完成的調用計數器並將回調編組到UI線程中。
public static void PreProcessCall(Action action)
{
Logger.LogDebugMessage("Pre-processing call for {0}", (new StackTrace()).GetFrame(1).GetMethod().Name);
Interlocked.Increment(ref pendingCalls);
ThreadPool.QueueUserWorkItem(o =>
{
try
{
action();
}
catch (System.Exception ex)
{
DataPublisher.GetPublisher().RaiseDataProcessExceptionOccurred(ex, ex.Message);
UpdatePendingCalls();
}
});
}
private static void UpdatePendingCalls()
{
Interlocked.Decrement(ref pendingCalls);
Debug.Assert(pendingCalls >= 0, "The number of pending calls should never go below zero.");
if (pendingCalls <= 0)
{
lock (pendingCallNotifications)
{
while (pendingCallNotifications.Count > 0)
{
Action callback = pendingCallNotifications.Dequeue();
Globals.Dispatcher.BeginInvoke(callback);
}
}
}
}
public static void PostProcessCall(Action action)
{
Logger.LogDebugMessage("Post-processing call for {0}", (new StackTrace()).GetFrame(1).GetMethod().Name);
UpdatePendingCalls();
Globals.Dispatcher.BeginInvoke(() =>
{
try
{
action();
}
catch (System.Exception ex)
{
DataPublisher.GetPublisher().RaiseDataProcessExceptionOccurred(ex, ex.Message);
}
});
}
因此,一個典型的調用看起來是這樣的:
public void SendMessage(string message, OperationCallback callback)
{
DataConnectionManager.PreProcessCall(() =>
{
Logger.LogDebugMessage("SendChatMessage");
notificationClient.SendChatMessageAsync(roomViewModel.SessionId, message, callback);
});
}
void RoomService_SendChatMessageCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
OperationCallback callback = (OperationCallback)e.UserState;
DataConnectionManager.PostProcessCall(() =>
{
if (callback != null)
{
callback(e.Error);
}
Logger.LogDebugMessage("SendChatMessageCompleted.");
});
}
就像我說的,基本上你已經嘗試過。
不是開箱即用的,但是當您調用BeginXXXX並將其設置回來時,設置一個小布爾標誌會相當容易,那麼輸入EndXXX回調,不是嗎? – 2010-01-19 22:14:17