代码(内容参考于http://msdn2.microsoft.com/zh-cn/library/wyd0d1e5(VS.80).aspx):
Imports System
Imports System.Runtime.Remoting.MessagingPublic Class TestCallback
Public Shared Sub Main()
' 传入参数的设定
Dim factorizableStr As String = "20000011" ' XML Web Service的实例生成
Dim pf As JyuchuServices = New JyuchuServices ' Instantiate an AsyncCallback delegate to use as a
' parameter
' in the BeginFactorize method.
Dim cb As AsyncCallback
cb = New AsyncCallback(AddressOf TestCallback.FactorizeCallback) ' Begin the Async call to Factorize, passing in the
' AsyncCallback delegate and a reference to our instance
' of PrimeFactorizer.
Dim ar As IAsyncResult = pf.BeginGetMessage(factorizableStr, cb, pf) ' Keep track of the time it takes to complete the async call as
' the call proceeds.
Dim start As Integer = DateTime.Now.Second
Dim currentSecond As Integer = start
Do While (ar.IsCompleted = False)
If (currentSecond < DateTime.Now.Second) Then
currentSecond = DateTime.Now.Second
Console.WriteLine("Seconds Elapsed..." & _
(currentSecond - start).ToString())
End If
Console.WriteLine("unfinished")
Loop ' Once the call has completed, you need a method to ensure the
' thread executing this Main function
' doesn't complete prior to the callback function completing.
Console.Write("Press Enter to quit")
Dim quitchar As Integer = Console.Read()
End Sub ' Set up the call-back function that is invoked by the proxy
' class when the asynchronous operation completes.
Public Shared Sub FactorizeCallback(ByVal ar As IAsyncResult) ' You passed in the instance of PrimeFactorizer in the third
' parameter to BeginFactorize, which is accessible in the
' AsyncState property.
Dim pf As JyuchuServices = ar.AsyncState
Dim results As String ' Get the completed results.
results = pf.EndGetMessage(ar) 'Output the results.
Console.Write("factors into: " & results)
End Sub
End Class问题:
根据msdn上的例子,我想用上面的代码实现异步回调方法,但程序运行时,始终走不到FactorizeCallback方法,也就是没有实现回调,ar.IsCompleted始终为false,程序就卡在Do While (ar.IsCompleted = False)这个循环体里。
用sniff监查XML Web Service服务器,发现Service已经接收到了请求,并且将正确信息返回给客户端了,但客户端的IAsyncResult的IsCompleted却始终为false,不知是为什么?
在上述代码的Dim ar As IAsyncResult = pf.BeginGetMessage(factorizableStr, cb, pf)语句后,加一句ar.AsyncWaitHandle.WaitOne()时,FactorizeCallback方法被回调,很奇怪,如此一来实际上是用等待方法实现了异步,回调方法应该是不需要直接写等待语句的,BeginGetMessage异步开始后,直接就会运行其以下的其他代码,当IsCompleted为true时,程序会自动执行(回调)FactorizeCallback方法,不知道我的理解是否正确?
请各位朋友给我点思路和方法,我上面的代码不能实现回调,问题到底出在哪里?在不加入WaitOne()时,如何来真正运用回调方法?
问题较急,谢谢各位了!
Imports System
Imports System.Runtime.Remoting.MessagingPublic Class TestCallback
Public Shared Sub Main()
' 传入参数的设定
Dim factorizableStr As String = "20000011" ' XML Web Service的实例生成
Dim pf As JyuchuServices = New JyuchuServices ' Instantiate an AsyncCallback delegate to use as a
' parameter
' in the BeginFactorize method.
Dim cb As AsyncCallback
cb = New AsyncCallback(AddressOf TestCallback.FactorizeCallback) ' Begin the Async call to Factorize, passing in the
' AsyncCallback delegate and a reference to our instance
' of PrimeFactorizer.
Dim ar As IAsyncResult = pf.BeginGetMessage(factorizableStr, cb, pf) ' Keep track of the time it takes to complete the async call as
' the call proceeds.
Dim start As Integer = DateTime.Now.Second
Dim currentSecond As Integer = start
Do While (ar.IsCompleted = False)
If (currentSecond < DateTime.Now.Second) Then
currentSecond = DateTime.Now.Second
Console.WriteLine("Seconds Elapsed..." & _
(currentSecond - start).ToString())
End If
Console.WriteLine("unfinished")
Loop ' Once the call has completed, you need a method to ensure the
' thread executing this Main function
' doesn't complete prior to the callback function completing.
Console.Write("Press Enter to quit")
Dim quitchar As Integer = Console.Read()
End Sub ' Set up the call-back function that is invoked by the proxy
' class when the asynchronous operation completes.
Public Shared Sub FactorizeCallback(ByVal ar As IAsyncResult) ' You passed in the instance of PrimeFactorizer in the third
' parameter to BeginFactorize, which is accessible in the
' AsyncState property.
Dim pf As JyuchuServices = ar.AsyncState
Dim results As String ' Get the completed results.
results = pf.EndGetMessage(ar) 'Output the results.
Console.Write("factors into: " & results)
End Sub
End Class问题:
根据msdn上的例子,我想用上面的代码实现异步回调方法,但程序运行时,始终走不到FactorizeCallback方法,也就是没有实现回调,ar.IsCompleted始终为false,程序就卡在Do While (ar.IsCompleted = False)这个循环体里。
用sniff监查XML Web Service服务器,发现Service已经接收到了请求,并且将正确信息返回给客户端了,但客户端的IAsyncResult的IsCompleted却始终为false,不知是为什么?
在上述代码的Dim ar As IAsyncResult = pf.BeginGetMessage(factorizableStr, cb, pf)语句后,加一句ar.AsyncWaitHandle.WaitOne()时,FactorizeCallback方法被回调,很奇怪,如此一来实际上是用等待方法实现了异步,回调方法应该是不需要直接写等待语句的,BeginGetMessage异步开始后,直接就会运行其以下的其他代码,当IsCompleted为true时,程序会自动执行(回调)FactorizeCallback方法,不知道我的理解是否正确?
请各位朋友给我点思路和方法,我上面的代码不能实现回调,问题到底出在哪里?在不加入WaitOne()时,如何来真正运用回调方法?
问题较急,谢谢各位了!
解决方案 »
- 浏览器阻止activeX怎么办?
- c# 后厨 代码源码(送分了)
- 生成项目的版权问题
- SharpZipLib 压缩问题
- ImageFormat.Png 保存后无透明效果?
- 有一点winform的开发经验,想学习WPF,烦各位给推荐几本好的书
- C#如何获得随处文件的路径?
- 关于C# Form程序设计中遇到的几个问题(重金求解! 请帮忙!)
- 怎样判断SelectedItem的类型
- 怎样设置OpenFileDialog组件的Filter,使实现一次过滤出多种扩展名的文件??
- 在C#中生成excel报表时怎么编辑格式?
- 一个页面由很多独立的Table由上至下组成,每个Table中都要从数据库访问大量数据,现在的问题是:
http://www.codeproject.com/cs/webservices/async_xmlws.asp
http://www.codeproject.com/cs/webservices/AdvAsynchWebService.asp
--------------------------------------------------------------
所以说 Begin 方法还没返回 IAsyncResult 就进入Do While循环体了
ar.IsCompleted 就一直为 False
↓以下代码是用wsdl自动生成的proxy代码,请作为参考-_-'------------------------------------------------------------------------------
' <autogenerated>
' This code was generated by a tool.
' Runtime Version: 1.1.4322.2032
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </autogenerated>
'------------------------------------------------------------------------------Option Strict Off
Option Explicit OnImports System
Imports System.ComponentModel
Imports System.Diagnostics
Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.Xml.Serialization'
'由wsdl自动生成。Version=1.1.4322.2032。
''<res/>
<System.Diagnostics.DebuggerStepThroughAttribute(), _
System.ComponentModel.DesignerCategoryAttribute("code"), _
System.Web.Services.WebServiceBindingAttribute(Name:="JyuchuServicesSoap", [Namespace]:="http://localhost/JyuchuWebService/JyuchuServices")> _
Public Class JyuchuServices
Inherits System.Web.Services.Protocols.SoapHttpClientProtocol
'<res/>
Public Sub New()
MyBase.New
Me.Url = "http://***.***.***.***/JyuchuWebService/JyuchuServices.asmx"
End Sub
'<res/>
<System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://localhost/JyuchuWebService/JyuchuServices/GetMessage", RequestNamespace:="http://localhost/JyuchuWebService/JyuchuServices", ResponseNamespace:="http://localhost/JyuchuWebService/JyuchuServices", Use:=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle:=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)> _
Public Function GetMessage(ByVal OrderNumber As String) As String
Dim results() As Object = Me.Invoke("GetMessage", New Object() {OrderNumber})
Return CType(results(0),String)
End Function
'<res/>
Public Function BeginGetMessage(ByVal OrderNumber As String, ByVal callback As System.AsyncCallback, ByVal asyncState As Object) As System.IAsyncResult
Return Me.BeginInvoke("GetMessage", New Object() {OrderNumber}, callback, asyncState)
End Function
'<res/>
Public Function EndGetMessage(ByVal asyncResult As System.IAsyncResult) As String
Dim results() As Object = Me.EndInvoke(asyncResult)
Return CType(results(0),String)
End Function
End Class
-------------------------------------------------------------
Begin只是异步的开始,相当于thread.start();
在没得到服务器的响应前,主线程就到do while 了而用ar.AsyncWaitHandle.WaitOne(),则主线程会在这里等待,直到服务器响应。
我提问的代码里之所以写了do while 语句,就是为了等待线程收到服务器的响应,用do while 语句来循环等待,否则还未收到服务器的响应,程序就运行结束了,我用do while 循环来等,但却始终(永远)等不到服务器的响应,也就是IAsyncResult的IsCompleted始终(永远)为false,不知道是为什么?to:Knight94(愚翁)
谢谢你的例子。
http://www.codeproject.com/cs/webservices/async_xmlws.asp里的代码我已经在本机运行了,对于异步回调是成功的,能实现的,但我比较了自己写的代码,没有发现有什么不一样之处(无非一个用C#语言,我用的是VB.net语言),难道web service处会有问题?那为什么用异步等待的方法却是可以实现的,我非常的困惑,请各位提供我思路和方法,谢谢!!
你以上的代码这么多,外人看来很难分析出结果。
我用C#代替VB.net写,尽然能回调了。
下面是用C#和VB.net实现的代码,麻烦比较一下,到底哪里有问题?using System;
using System.Runtime.Remoting.Messaging;public class TestProxy
{
private static bool bEnd=false;
public static void JyuchuServicesCallback(IAsyncResult arResult)
{
JyuchuServices js=(JyuchuServices)arResult.AsyncState;
// call "EndGetMessage" and get the result..
String strResult = js.EndGetMessage(arResult);
// show the result of the webservice call..
Console.WriteLine("Async. WebService call " + strResult);
// set flag so that application can terminate...
bEnd=true;
}
public static void Main()
{
JyuchuServices js = new JyuchuServices();
AsyncCallback acb = new AsyncCallback(TestProxy.JyuchuServicesCallback); js.BeginGetMessage("20000011",acb,js);
Console.WriteLine("Waiting for webservice to end..");
while(bEnd==false);
Console.WriteLine("Over!");
}
};
------------------------------------------------------------------------------
Imports System
Imports System.Runtime.Remoting.MessagingPublic Class TestCallback
Private Shared bEnd As Boolean = False Public Shared Sub JyuchuServicesCallback(ByVal ar As IAsyncResult)
Dim js As JyuchuServices = ar.AsyncState
' call "EndGetMessage" and get the result..
Dim results As String = js.EndGetMessage(ar)
' show the result of the webservice call..
Console.WriteLine("Async. WebService call " & results)
' set flag so that application can terminate...
bEnd = True
End Sub Public Shared Sub Main()
Dim js As JyuchuServices = New JyuchuServices Dim acb As AsyncCallback = New AsyncCallback(AddressOf TestCallback.JyuchuServicesCallback) js.BeginGetMessage("20000011", acb, js) Console.WriteLine("Waiting for JSwebservice to end..")
While (bEnd = False)
End While
Console.Write("Over!")
End Sub
End Class
我看上面的两段代码虽然用不同语言实现,但从语义上应该是完全一样的,为什么用C#写的代码能实现机能,而用VB.net写的却不行,真是非常的奇怪,请各位再帮忙看看,谢谢了!!
看看C#和VB.net的Web.Config就知道有点差别了,就连注释一个英文一个中文
但为何要在触发事件后才能解决问题,至于具体的原因还不是很清楚。总结一下:
我在前面提问了关于C#和VB.net写出的相同语义的回调方法,为何结果会不同?
经过这几天的实验和各位朋友的提醒,可能原因如下:
1、C#写出语言的执行速度要比VB.net的快的多。
2、由于速度上的偏差,导致相同语义的代码,运行的结果会不一样(特别在异步运用时,尤明显)
3、由于VB.net生成的代码执行速度慢,在还未得到(或处理到)WebService的返回结果时,程序就已经执行到了while循环体里,此时却消耗了大量的cpu资源,导致Begin的异步线程无法完成和ar.IsCompleted始终为false。C#生成的代码执行速度快,在未执行到while语句前,侥幸能异步回调。
4、我写的代码不是很好,在异步线程Begin后就直接要等待结果的程序(逻辑)不适合异步的回调方法,如果要用的话,可能就要用到System.Threading.Thread.Sleep方法,但这样的话Sleep时间的长短将又是一个问题。在我看来还不如用异步等待方法来的直接和有效。终于解决了问题,松了一口气,客户要求用回调方法实现,没有办法啊,但毕竟我也学了一些东西,最后再感谢一下各位朋友的回答。