async await的问题

shewea 2013-11-07 04:23:27
公司给了我一个临时的任务,让我用做一个WP8的程序,我没做过C#.现在求大家帮忙看看这段代码.
这个程序是手机跟设备通过蓝牙接收数据的程序.
因为大量使用了async和await,彻底把我搞糊涂了

public static async Task<byte[]> receiveData()
{
int K = 1024;
byte[] readBuffer = new byte[K * 4];

Boolean c0flag = true;

///初始化缓冲区,根据设置的最大值 * 4
if (readBuffer == null)
{
readBuffer = new byte[K * 4];
}

DateTime lstart = DateTime.Now;
int i = 0;
do
{
await dataReader.LoadAsync(1);
uint l = dataReader.UnconsumedBufferLength;
byte b = dataReader.ReadByte();
readBuffer[i++] = b;

if (b == Frame.B_EOF) {
readBuffer[i] = b;
break;
}

}while (c0flag/* && (DateTime.Now - lstart).Seconds < TIME_OUT*/);
byte[] returnBuf = new byte[i];

System.Buffer.BlockCopy(readBuffer, 0, returnBuf, 0,i);

return returnBuf;
}
这是一段接收蓝牙数据的过程
我测试过了,没什么问题的
但是调用的时候
var r = await BluetoothConn.writeData(frame.getFrameBuf());
if(r)
{
var result = await BluetoothConn.receiveData(); //1.接收ACK
if (result.Length > 0)
{
Deployment.Current.Dispatcher.BeginInvoke(async () =>
{
MessageBox.Show(Frame.bytes2string(result));
});

var result2 = await BluetoothConn.receiveData();//2.接收应答
Frame frame2 = new Frame();
frame2.storeData(result, 0, result2.Length);
}
}

如代码所示:
发送完数据以后
1.应该接收ACK
2.接收设备的应答
但是现在这两个接收的过程彻底乱了,我查了一些资料,做了一些实验.然后我彻底迷糊了.
我猜测啊:
B函数里使用await,然后A函数里调用了B函数
B函数await 的时候 当前await的代码会卡住(就是将任务抛出去异步执行),当前await代码(B函数)下面的代码不会执行,然后跳出去继续执行"调用自己(也就是A函数)"的方法
但是A函数调用B函数的时候 也是await的
我做过测试,在windows form程序里,await是会停下来的即使await的方法里面也有await
但是WP里 就乱了 代码如上



这是我在Windows Form里的代码


private async Task<long> awaWrapper(String str)
{
this.richTextBox1.Text += String.Format("\n " + str + "在等待\r\n");
await AccessWebAsync(str);

this.richTextBox1.Text += String.Format("\n " + str + "在等待\r\n");

return 0;
}

private async Task<long> AccessWebAsync(String str)
{
MemoryStream content = new MemoryStream();

// 对MSDN发起一个Web请求
HttpWebRequest webRequest = WebRequest.Create("http://msdn.microsoft.com/zh-cn/") as HttpWebRequest;
if (webRequest != null)
{
// 返回回复结果
using (WebResponse response = await webRequest.GetResponseAsync())
{
using (Stream responseStream = response.GetResponseStream())
{
await responseStream.CopyToAsync(content);
}
}
}

this.richTextBox1.Text += String.Format("\n " + str + "回复的字节长度为: {0}.\r\n", content.Length);
return content.Length;
}
private void OtherWork()
{
this.richTextBox1.Text += "\r\n等待服务器回复中.................\r\n";
}




调用过程1.

private async void button1_Click(object sender, EventArgs e)
{
AccessWebAsync("AAAAAAAAAAAAAAAAAAAA");
AccessWebAsync3("BBBBBBBBBBBBBBBBBBBB");
OtherWork();
}
结果:
等待服务器回复中.................

BBBBBBBBBBBBBBBBBBBB回复的字节长度为: 11314.

AAAAAAAAAAAAAAAAAAAA回复的字节长度为: 57313.

调用过程2:

private async void button1_Click(object sender, EventArgs e)
{
await AccessWebAsync("AAAAAAAAAAAAAAAAAAAA");
await AccessWebAsync3("BBBBBBBBBBBBBBBBBBBB");
OtherWork();
}
AAAAAAAAAAAAAAAAAAAA回复的字节长度为: 57313.

BBBBBBBBBBBBBBBBBBBB回复的字节长度为: 11314.

等待服务器回复中.................








希望我说的很清楚 工作有点急 我现在的想法是 用一个方法将这个receiveData方法封装起来,做成同步的,没有接收到数据,我就不返回,现在管不了那么多了 先想办法做出来再说 合不合理后面再说

希望知道的人帮帮忙 不甚感激 谢谢
...全文
311 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
threenewbee 2013-11-22
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
直到.net4.0之前,我一直觉得.net framework总是发布非常不同凡响令人震撼的好功能。 但是到了.net4.5,到了await/async,我真的觉得“.net程序员要出麻烦了”。这种东西反而让真正高效率的异步程序难以编写出来,一帮人被训练为顺序式的思维习惯,怎么可能头脑清晰地编写大量异步多线程代码? 因此这个语法,是缺乏真正的创意、有害的!
不觉得。Metro的设计准则之一就是异步化。也许对于新手,await/async不容易理解,但是它的确是对于使用APM(异步处理模式)最大的简化。试想如果大量使用回调,不但代码复杂,而且转来转去才会让人转晕,即便你对APM很熟悉。 回到lz的问题,其实async在WinForms程序中等同于不用,在WPF程序中,它对于它的调用本身来说,它会等待异步完成再执行下面的代码。对于UI线程本身来说,它不会阻塞,也就是可以同时执行其它的事件处理函数。如果它们也是异步的话。
  • 打赏
  • 举报
回复
直到.net4.0之前,我一直觉得.net framework总是发布非常不同凡响令人震撼的好功能。 但是到了.net4.5,到了await/async,我真的觉得“.net程序员要出麻烦了”。这种东西反而让真正高效率的异步程序难以编写出来,一帮人被训练为顺序式的思维习惯,怎么可能头脑清晰地编写大量异步多线程代码? 因此这个语法,是缺乏真正的创意、有害的!
  • 打赏
  • 举报
回复
给你一个忠告: 尽量不要使用 awai/async。这在性能上跟Task差不多,但是从设计上则是一种非常垃圾的东西。 进行异步程序设计,你需要将应用程序方法设计为回调形式。只有这样,你才能比较头脑清晰和顺畅地大规模使用异步编程。 比如说有一个方法 public void method(string param1, Action<string> callback),如果你调用它的方法当然最为自然的方式也仍然是这样的回调式的。 而await/async是给那种只知道使用同步代码的人使用的,而不是上述这种思路的人使用的。 于是你就会糊涂了。await/async看似傻瓜,实际上绕了一大圈,掩盖了真相。你时时刻刻被它绕进去。 进行异步程序设计,使用回调的形式。尽量丢弃await/async语法!

110,502

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧