自定义InteractiveChannelInitializer(InvocationConfirmationInteractiveChannelInitializer)定义如下。我们在BeginDisplayInitializationUI方法中弹出一个确认对话框,并将用户的确认选择封装到一个简单的AsyncResult对象中返回。在EndDisplayInitializationUI方法中,通过AsyncResult对象确认用户是否取消本次服务调用,如果是则抛出一个自定义的InvocationCancelException异常。
1: public class InvocationConfirmationInteractiveChannelInitializer : IInteractiveChannelInitializer 2: { 3: public const string ConfirmMessage = "程序执行过程涉及到WCF服务调用,是否继续?"; 4: public IAsyncResult BeginDisplayInitializationUI(IClientChannel channel, AsyncCallback callback, object state) 5: { 6: bool cancel = MessageBox.Show(ConfirmMessage, "WCF服务调用确认", MessageBoxButtons.YesNo) == DialogResult.No; 7: return new SimpleAsynsResult(cancel); 8: } 9: 10: public void EndDisplayInitializationUI(IAsyncResult result) 11: { 12: SimpleAsynsResult asyncResult = (SimpleAsynsResult)result; 13: if((bool)asyncResult.AsyncState) 14: { 15: throw new InvocationCancelException("WCF服务调用被取消"); 16: } 17: } 18: } 19: 20: public class SimpleAsynsResult:IAsyncResult 21: { 22: public SimpleAsynsResult(object state) 23: { 24: this.AsyncState = state; 25: } 26: 27: public object AsyncState { get; private set; } 28: public WaitHandle AsyncWaitHandle { get; private set; } 29: public bool CompletedSynchronously 30: { 31: get { return true; } 32: } 33: public bool IsCompleted 34: { 35: get { return true; } 36: } 37: }
我们通过一个自定义的ContractBehavior(InvocationConfirmationBehaviorAttribute )将上面自定义的InvocationConfirmationInteractiveChannelInitializer应用到客户端运行时。如下面的代码片断所示,在实现的ApplyClientBehavior方法中,我们创建了一个InvocationConfirmationInteractiveChannelInitializer对象并将其添加到客户端运行时的InteractiveChannelInitializers集合中。
1: [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)] 2: public class InvocationConfirmationBehaviorAttribute : Attribute, IContractBehavior 3: { 4: public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } 5: public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) 6: { 7: clientRuntime.InteractiveChannelInitializers.Add(new InvocationConfirmationInteractiveChannelInitializer()); 8: } 9: public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) { } 10: public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) { } 11: }
以特性形式定义的InvocationConfirmationBehaviorAttribute直接以如下的方式直接应用到作为服务契约的ICalcualtor接口中:
: [ServiceContract(Name = "CalculatorService", Namespace ="http://www.artech.com/")] 2: [InvocationConfirmationBehavior] 3: public interface ICalculator 4: { 5: [OperationContract] 6: double Add(double x, double y); 7: }
那么在进行服务调用的时候,确认对话框会自动弹出来。如果用户选择终止当前服务调用,那么InvocationCancelException异常会被抛出来,我们只需要捕捉该类型的异常即可。如下所示的是“=”按钮的Click事件代码:
1: public partial class Form1 : Form 2: { 3: //其他成员 4: private void buttonCalculate_Click(object sender, EventArgs e) 5: { 6: this.textBoxResult.Text = string.Empty; 7: using (ChannelFactory<ICalculator> channelfactory = new ChannelFactory<ICalculator>("calculatorservice")) 8: { 9: ICalculator calculator = channelfactory.CreateChannel(); 10: try 11: { 12: double op1 = double.Parse(this.textBoxOp1.Text); 13: double op2 = double.Parse(this.textBoxOp2.Text); 14: double result = calculator.Add(op1,op2); 15: this.textBoxResult.Text = result.ToString(); 16: } 17: catch (InvocationCancelException) 18: { 19: } 20: catch (Exception ex) 21: { 22: MessageBox.Show(ex.Message); 23: } 24: } 25: } 26: }
1: public class InvocationConfirmationInteractiveChannelInitializer : IInteractiveChannelInitializer
2: {
3: public const string ConfirmMessage = "程序执行过程涉及到WCF服务调用,是否继续?";
4: public IAsyncResult BeginDisplayInitializationUI(IClientChannel channel, AsyncCallback callback, object state)
5: {
6: bool cancel = MessageBox.Show(ConfirmMessage, "WCF服务调用确认", MessageBoxButtons.YesNo) == DialogResult.No;
7: return new SimpleAsynsResult(cancel);
8: }
9:
10: public void EndDisplayInitializationUI(IAsyncResult result)
11: {
12: SimpleAsynsResult asyncResult = (SimpleAsynsResult)result;
13: if((bool)asyncResult.AsyncState)
14: {
15: throw new InvocationCancelException("WCF服务调用被取消");
16: }
17: }
18: }
19:
20: public class SimpleAsynsResult:IAsyncResult
21: {
22: public SimpleAsynsResult(object state)
23: {
24: this.AsyncState = state;
25: }
26:
27: public object AsyncState { get; private set; }
28: public WaitHandle AsyncWaitHandle { get; private set; }
29: public bool CompletedSynchronously
30: {
31: get { return true; }
32: }
33: public bool IsCompleted
34: {
35: get { return true; }
36: }
37: }