好的,我有一些代码可以呈现。这是NetworkStream
对象的扩展方法。
public async static Task<byte[]> ReadDataAsync(this NetworkStream clientStream)
{
byte[] data = {};
var buffer = new byte[1024];
if (clientStream.CanRead)
{
using (var ms = new MemoryStream())
{
try
{
int bytesRead;
while (clientStream.DataAvailable &&
(bytesRead = await clientStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
await ms.WriteAsync(buffer, 0, bytesRead);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return data;
}
data = ms.ToArray();
}
}
else
{
Console.WriteLine("Closing clientStream.");
clientStream.Close();
}
return data;
}
我尝试调用此方法的代码。
public async static Task Preform(Socket client)
{
var stream = new NetworkStream(client);
var data = await stream.ReadDataAsync();
var message = await MessageFabrique.DeserializeMessage(data);
ServerCollections.Instance.ServerIssueQueue.Add(new ServerIssue
{
Message = message,
ClientStream = stream
});
}
ReadDataAsync
方法总是将我返回到一个空数组。在我尝试反序列化数据的那一刻,有一个例外 - 因为data[0]
。请帮我。为什么会发生这种情况,如果await
保证我的结果,何时需要?
答案 0 :(得分:4)
clientStream.DataAvailable
并不意味着将来可能会出现数据。这意味着现在可以使用数据进行阅读。摆脱它并且只是读取,读取将阻塞直到数据显示或当流命中它结束时将返回0。
答案 1 :(得分:0)
答案 2 :(得分:0)
除了其他答案之外,您可能还想创建同步上下文。有关详细信息,请参阅this article。
摘要是async / await在控制台应用程序中的工作方式与在UI应用程序中的工作方式不同。默认情况下,WPF和WebForms应用程序具有同步上下文,但控制台应用程序不具备此功能。结果(实际上非常明显&#34;广告宣传效果不佳&#34;在文档中)是async / await的行为 在控制台应用程序中的可预测性低于在UI应用程序中的行为,这可能会使它无法正常工作&#34;正如所宣传的那样#34;在某些情况下。
例如,在UI应用程序中&#34; async&#34;并不一定意味着代码在后台线程上运行。这相当于&#34;我准备好后再回到我身边。&#34;作为类比,考虑出去和10个人一起吃饭:当服务员来的时候,他要求订购的第一个人还没有准备好。这里的两个不好的解决方案是:a)引入第二个服务员等待第一个人准备好或接受其他9个人的命令)或b)等到第一个人准备好开始接受订单。最好的方法是接受其他9个人的命令然后回到第一个希望他到那时准备好的人。过度简化的风险基本上是异步在UI中的工作原理(除非你明确地将代码放在后台线程上,使用像Task.Run这样的东西)。但是,在使用异步的控制台应用程序中,无法保证代码实际运行的位置。
但是,如果您按照我链接到它的文章中所述添加同步上下文,则会以更加可预测的方式运行。