求助:异步调用System.IO.FileStream的BeginRead的返回值IAsyncResult的IsCompleted属性的问题 本帖最后由 yayiba2020 于 2013-02-13 12:00:49 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 请各位帮我看一下为什么第二段代码异步调用未完成时IsCompleted的属性会为true 你在异步回调中Thread.Sleep(6000);是毫无意义的,那个result.IsCompleted指示了异步操作的完成,并不是异步回调的完成,当异步操作完成后,就会更改IsCompleted的属性值为true,并执行异步回调函数。既然你用到了异步回调函数,根本不需要在主线程中轮询异步状态,直接把后续操作写在异步回调中即可。 很高兴能看到有人能关注我的问题。Thread.Sleep(6000);可以让异步回调有一定的运行耗时时间,便于调试,在MSDN的示例中也是这样写的(请参见第一段代码)MSDN对于IsCompleted的解释就是异步回调的完成,您看一下第一段代码,它也是这样去判断的,等回调完成后(IsCompleted为true)进行后续操作。而且我调试过没有问题。 msdn:http://msdn.microsoft.com/zh-cn/library/system.iasyncresult.iscompleted.aspx哪里“解释说是异步回调的完成”? 你的代码可以改一下:static void Main(string[] args){ APM_4_1();}/// <summary>/// 采用主线程轮询判断异步处理是否完成的方式解决异步编程的同步问题/// </summary>private static void APM_4_1(){ Console.WriteLine("主程序中!"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); Console.WriteLine(); string path = "demo.log"; byte[] buffer = new byte[4096]; System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.Open); IAsyncResult result = fs.BeginRead(buffer, 0, 4096, delegate(IAsyncResult ar) { Thread.Sleep(6000); Console.WriteLine("第三步操作结束后的异步回调。"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); Console.WriteLine("ar.IsCompleted 属性值为 {0}。", ar.IsCompleted); int length = fs.EndRead(ar); string message = System.Text.Encoding.UTF8.GetString(buffer, 0, length); Console.WriteLine(message); Console.WriteLine(); }, null); Console.WriteLine("第一步操作已经完成。现在主程序继续进行!"); Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId); Console.WriteLine(); Console.WriteLine("回车后结束程序。"); Console.WriteLine(); Console.ReadLine();} 对不住了两位,是我自己没有理解异步操作和异步回调的概念,你们都说得对!第一段代码中用委托的BeginInvoke方法是异步操作,第二段代码使用BeginRead也是异步操作但其中使用了一个回调匿名方法这个回调是异步回调(当BeginRead执行完后后再去调用匿名函数)。MSDN的解释确实是异步操作的完成,我当时概念没理解清楚把异步操作和异步回调弄混了。另外第二段代码是国内某本口碑很好的一本书上的代码,这本书的内容设计的很不错,但是有些地方不够严谨吧,这段代码我正好跑了一下结果有问题,如果不解决这问题我的书不就白读了虽然问题解决了,我学到了东西,但却证明书上是错的,我真是很开心但又有些难过,看到MSDN的代码一目了然,那本书上的示例代码却让人觉得难懂而且感到困惑也许这是国内书的通病吧。 请问C#语言有没有类似java解惑(Java Puzzlers)那种经典宝书? C#调用VC写的DLL问题,急,在线等,问题解决,马上结贴 C# 操作EXCEL DataGridView1的Frozen问题 异步通信的问题 winform中DataSet.WriteXml如何把排序后的DataSet写入xml文件 .Net中的“五星控件”和“级联菜单控件”? 兄弟们在.Net中UIP框架用过吗?? 有什么办法使.Net写的程序跟用Java写的程序相互调用,除了WebService? 请问如何剔除干扰的数据 动态生成控件读取值 请高手帮着分析这个算法怎么计算的
既然你用到了异步回调函数,根本不需要在主线程中轮询异步状态,直接把后续操作写在异步回调中即可。
Thread.Sleep(6000);可以让异步回调有一定的运行耗时时间,便于调试,在MSDN的示例中也是这样写的(请参见第一段代码)
MSDN对于IsCompleted的解释就是异步回调的完成,您看一下第一段代码,它也是这样去判断的,等回调完成后(IsCompleted为true)进行后续操作。而且我调试过没有问题。
msdn:http://msdn.microsoft.com/zh-cn/library/system.iasyncresult.iscompleted.aspx
哪里“解释说是异步回调的完成”?
你的代码可以改一下:static void Main(string[] args)
{
APM_4_1();
}/// <summary>
/// 采用主线程轮询判断异步处理是否完成的方式解决异步编程的同步问题
/// </summary>
private static void APM_4_1()
{
Console.WriteLine("主程序中!");
Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(); string path = "demo.log";
byte[] buffer = new byte[4096]; System.IO.FileStream fs = new System.IO.FileStream(path, System.IO.FileMode.Open);
IAsyncResult result = fs.BeginRead(buffer, 0, 4096,
delegate(IAsyncResult ar)
{
Thread.Sleep(6000);
Console.WriteLine("第三步操作结束后的异步回调。");
Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("ar.IsCompleted 属性值为 {0}。", ar.IsCompleted);
int length = fs.EndRead(ar);
string message = System.Text.Encoding.UTF8.GetString(buffer, 0, length);
Console.WriteLine(message);
Console.WriteLine();
},
null); Console.WriteLine("第一步操作已经完成。现在主程序继续进行!");
Console.WriteLine("线程的 Id: {0}", Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(); Console.WriteLine("回车后结束程序。");
Console.WriteLine(); Console.ReadLine();
}
对不住了两位,是我自己没有理解异步操作和异步回调的概念,你们都说得对!
第一段代码中用委托的BeginInvoke方法是异步操作,第二段代码使用BeginRead也是异步操作但其中使用了一个回调匿名方法这个回调是异步回调(当BeginRead执行完后后再去调用匿名函数)。
MSDN的解释确实是异步操作的完成,我当时概念没理解清楚把异步操作和异步回调弄混了。另外第二段代码是国内某本口碑很好的一本书上的代码,这本书的内容设计的很不错,但是有些地方不够严谨吧,这段代码我正好跑了一下结果有问题,如果不解决这问题我的书不就白读了
虽然问题解决了,我学到了东西,但却证明书上是错的,我真是很开心但又有些难过,看到MSDN的代码一目了然,那本书上的示例代码却让人觉得难懂而且感到困惑也许这是国内书的通病吧。