您的位置:首页 > 其它

在 .NET 中使用 WEB SERVICE 的CallBacks机制 (4)

2008-04-24 16:29 435 查看
测试WEB SERVICE CallBacks的概念和设计能使用下列位于http://localhost虚拟目录的三个子项目一起测试。测试的概要已经在上述段落中(WEB SERVICE Callback部分)说明。所有项目已经加入了跟踪断点,这样我们可以清楚的看到程序运行的过程(http://www.sysinternals.com/)。下面是它们的实现代码:1. WEB SERVICE Anamespace WEBSERVICEA{ public class SERVICEA : System.WEB.SERVICEs.WEBSERVICE { public SERVICEA() { //CODEGEN: This call is required by the ASP.NET WEB SERVICEs Designer InitializeComponent(); Trace.WriteLine(string.Format("[{0}]SERVICEA.ctor", GetHashCode())); } #region Component Designer generated code private void InitializeComponent() { } #endregion protected override void Dispose( bool disposing ) { Trace.WriteLine(string.Format("[{0}]SERVICEA.Dispose", GetHashCode())); } [WEBMethod] public string DoSomeWorkA(int count, string ticket) { Trace.WriteLine(string.Format("[{0}]SERVICEA.DoSomeWorkA start...", GetHashCode())); int startTC = Environment.TickCount; // current state Global.state[ticket] = "The job has been started"; string state = ticket; // location of the source/target WEB SERVICEs - // (hard coded for test purpose only!) string myWsdlUrl = "http://localhost/WEBSERVICEA/SERVICEA.asmx?wsdl"; string targetWsdlUrl = "http://localhost/WEBSERVICEB/SERVICEB.asmx?wsdl"; // call the WEBSERVICE B WEBSERVICEAccessor wsa = new WEBSERVICEAccessor(targetWsdlUrl); object esObj = wsa.CreateInstance("SERVICEB"); object retval = wsa.Invoke(esObj, "BeginDoSomeWorkB", count, myWsdlUrl, state, null, null); // Wait for the call to complete WEBClientAsyncResult ar = retval as WEBClientAsyncResult; ar.AsyncWaitHandle.WaitOne(); // retrieve a result object result = wsa.Invoke(esObj, "EndDoSomeWorkB", ar); int durationTC = Environment.TickCount - startTC; Trace.WriteLine(string.Format("[{0}]SERVICEA.DoSomeWorkA done in {1}ms", GetHashCode(), durationTC)); // Global.state.Remove(ticket); return result.ToString(); } [WEBMethod] public bool CallbackSERVICEA(string sender, string xmlEventArg) { WEBSERVICEEventArgs ea = (WEBSERVICEEventArgs)xmlEventArg; string msg = string.Format( "[{0}]SERVICEA.CallbackSERVICEA({1}, [{2},{3},{4}])", GetHashCode(), sender, ea.name, ea.state, ea.param); if(Global.state.ContainsKey(ea.state)) { Global.state[ea.state] = string.Format("{0}, [{1},{2},{3}]", sender, ea.name, ea.state, ea.param); Trace.WriteLine(msg); return true; } return false; } [WEBMethod] public string AbortWorkA(string ticket) { Trace.WriteLine(string.Format("[{0}]SERVICEA.AbortWorkA", GetHashCode())); if(Global.state.ContainsKey(ticket)) { Global.state.Remove(ticket); return string.Format("#{0} aborted.", ticket); } return string.Format("#{0} doesn't exist.", ticket); } [WEBMethod] public string GetStatusWorkA(string ticket) { if(Global.state.ContainsKey(ticket)) { return string.Format("#{0} status: {1}", ticket, Global.state[ticket]); } return string.Format("#{0} doesn't exist.", ticket); } }}全局类: namespace WEBSERVICEA { public class Global : System.WEB.HttpApplication { static public Hashtable state = null; protected void Application_Start(Object sender, EventArgs e) { state = Hashtable.Synchronized(new Hashtable()); Trace.WriteLine(string.Format("[{0}]SERVICEA.Application_Start", GetHashCode())); } // ... protected void Application_End(Object sender, EventArgs e) { state.Clear(); Trace.WriteLine(string.Format("[{0}]SERVICEA.Application_End", GetHashCode())); } }}请求和Callback WEB Methods运行在不同的Session 中,这是状态为什么保存在可共享的资源类(如Hashtable)中的原因。每个客户端的请求有一个单独的票据凭证,它是WEB SERVICE和全球站点之间的一把通信钥匙(cookie)。2. WEB SERVICE B这个网络服务非常简单。 只有一个 WEB Methods模拟一些工作。 程序运行期间,服务开始启用Callback WEB Methods。工作以同步的方式在运行一些循环操作。每个循环调用WEBSERVICE”A”的Callback WEB Methods,基于它的返回值,程序可以自动停止。SERVICE. 可以在session中保持状态。 namespace WEBSERVICEB{ public class SERVICEB : System.WEB.SERVICEs.WEBSERVICE { public SERVICEB() { //CODEGEN: This call is required by the ASP.NET WEB SERVICEs Designer InitializeComponent(); Trace.WriteLine(string.Format("[{0}]SERVICEB.ctor", GetHashCode())); } #region Component Designer generated code private void InitializeComponent() { } #endregion protected override void Dispose( bool disposing ) { Trace.WriteLine(string.Format("[{0}]SERVICEB.Dispose", GetHashCode())); } [WEBMethod(EnableSession=true)] public string DoSomeWorkB(int count, string callbackWS, string stateWS) { Trace.WriteLine(string.Format("[{0}]SERVICEB.DoSomeWorkB start...", GetHashCode())); int startTC = Environment.TickCount; // async call to the SERVICEA.CallbackSERVICEA method WEBSERVICEAccessor wsa = new WEBSERVICEAccessor(callbackWS); object esObj = wsa.CreateInstance("SERVICEA"); // prepare the callback arguments: sender, EventArgs string sender = GetType().FullName; WEBSERVICEEventArgs ea = new WEBSERVICEEventArgs(); ea.name = "This is a callback"; ea.state = stateWS; for(int ii = 0; ii < (count & 0xff); ii++) // max. count = 255 { ea.param = ii; string xmlEventArgs = ea; object retval = wsa.Invoke(esObj, "BeginCallbackSERVICEA", sender, xmlEventArgs, null, null); // simulate some task Thread.Sleep(250); // Wait for the call to complete WEBClientAsyncResult ar = retval as WEBClientAsyncResult; ar.AsyncWaitHandle.WaitOne(); // result object result = wsa.Invoke(esObj, "EndCallbackSERVICEA", ar); if((bool)result == false) { Trace.WriteLine(string.Format( "[{0}]SERVICEB.DoSomeWorkB has been aborted", GetHashCode())); return string.Format("#{0} aborted during the progress of {1}.", stateWS, ii); } } // int durationTC = Environment.TickCount - startTC; Trace.WriteLine(string.Format("[{0}]SERVICEB.DoSomeWorkB done in {1}ms", GetHashCode(), durationTC)); return string.Format("#{0} done in {1}ms", stateWS, durationTC); } }}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: