C# Windows Phone 8.1 GetOutputStreamAsync(...) 首次使用后阻塞
C# Windows Phone 8.1 GetOutputStreamAsync(...) blocking after first use
我目前正在尝试创建一个非常基本的测试应用程序,它应该:
1) 在端口“1234”上广播 "sometext"
2) 稍等一下答案
3) Return 所有答案
虽然下面发布的解决方案第一次工作正常,但每个后续调用都会永远阻塞在:
stream = await socket.GetOutputStreamAsync(...)
直到现在我尝试了所有可能的清理方法(因为那是我认为失败的地方),甚至将所有内容都包装在 using(...) 语句中。
模拟器和使用 Windows Phone 8.1
的硬件设备都会出现问题
提前致谢!
启动"discovery"的代码:
private void Button_Click(object sender, RoutedEventArgs e)
{
PluginUDP pudp = new PluginUDP();
var task = pudp.scan("asf");
task.Wait();
foreach (string s in task.Result)
output.Text += s + "\r\n";
}
"discovery"本身的代码:
using System;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using namespace whatever
{
public class PluginUDP
{
private static readonly HostName BroadcastAddress = new HostName("255.255.255.255");
private static readonly string BroadcastPort = "1234";
private static readonly byte[] data = Encoding.UTF8.GetBytes("00wlan-ping00");
ConcurrentBag<string> receivers;
public async System.Threading.Tasks.Task<string[]> scan(string options)
{
receivers = new ConcurrentBag<string>();
receivers.Add("ok");
DatagramSocket socket = null;
IOutputStream stream = null;
DataWriter writer = null;
try
{
socket = new DatagramSocket();
socket.MessageReceived += MessageReceived;
await socket.BindServiceNameAsync("");
stream = await socket.GetOutputStreamAsync(BroadcastAddress, BroadcastPort);
writer = new DataWriter(stream);
writer.WriteBytes(data);
await writer.StoreAsync();
Task.Delay(1000).Wait();
}
catch (Exception exception)
{
receivers.Add(exception.Message);
}
finally
{
if (writer != null)
{
writer.DetachStream();
writer.Dispose();
}
if(stream != null)
stream.Dispose();
if(socket != null)
socket.Dispose();
}
return receivers.ToArray(); ;
}
private async void MessageReceived(DatagramSocket socket, DatagramSocketMessageReceivedEventArgs args)
{
try
{
var result = args.GetDataStream();
var resultStream = result.AsStreamForRead(1024);
using (var reader = new StreamReader(resultStream))
{
var text = await reader.ReadToEndAsync();
if (text.Contains("pong"))
{
receivers.Add(args.RemoteAddress.ToString());
}
}
}
catch (Exception exception)
{
receivers.Add("ERRCV");
}
}
}
}
您的问题从这里开始:
task.Wait();
You're blocking on async code,这会导致您陷入 僵局。
你想要:
private async void Button_Click(object sender, RoutedEventArgs e)
{
PluginUDP pudp = new PluginUDP();
string[] result = await pudp.scan("asf");
foreach (string s in result)
output.Text += s + "\r\n";
}
你还想做:
await Task.Delay(1000);
而不是:
Task.Delay(1000).Wait();
我目前正在尝试创建一个非常基本的测试应用程序,它应该:
1) 在端口“1234”上广播 "sometext"
2) 稍等一下答案
3) Return 所有答案
虽然下面发布的解决方案第一次工作正常,但每个后续调用都会永远阻塞在:
stream = await socket.GetOutputStreamAsync(...)
直到现在我尝试了所有可能的清理方法(因为那是我认为失败的地方),甚至将所有内容都包装在 using(...) 语句中。
模拟器和使用 Windows Phone 8.1
的硬件设备都会出现问题提前致谢!
启动"discovery"的代码:
private void Button_Click(object sender, RoutedEventArgs e)
{
PluginUDP pudp = new PluginUDP();
var task = pudp.scan("asf");
task.Wait();
foreach (string s in task.Result)
output.Text += s + "\r\n";
}
"discovery"本身的代码:
using System;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using namespace whatever
{
public class PluginUDP
{
private static readonly HostName BroadcastAddress = new HostName("255.255.255.255");
private static readonly string BroadcastPort = "1234";
private static readonly byte[] data = Encoding.UTF8.GetBytes("00wlan-ping00");
ConcurrentBag<string> receivers;
public async System.Threading.Tasks.Task<string[]> scan(string options)
{
receivers = new ConcurrentBag<string>();
receivers.Add("ok");
DatagramSocket socket = null;
IOutputStream stream = null;
DataWriter writer = null;
try
{
socket = new DatagramSocket();
socket.MessageReceived += MessageReceived;
await socket.BindServiceNameAsync("");
stream = await socket.GetOutputStreamAsync(BroadcastAddress, BroadcastPort);
writer = new DataWriter(stream);
writer.WriteBytes(data);
await writer.StoreAsync();
Task.Delay(1000).Wait();
}
catch (Exception exception)
{
receivers.Add(exception.Message);
}
finally
{
if (writer != null)
{
writer.DetachStream();
writer.Dispose();
}
if(stream != null)
stream.Dispose();
if(socket != null)
socket.Dispose();
}
return receivers.ToArray(); ;
}
private async void MessageReceived(DatagramSocket socket, DatagramSocketMessageReceivedEventArgs args)
{
try
{
var result = args.GetDataStream();
var resultStream = result.AsStreamForRead(1024);
using (var reader = new StreamReader(resultStream))
{
var text = await reader.ReadToEndAsync();
if (text.Contains("pong"))
{
receivers.Add(args.RemoteAddress.ToString());
}
}
}
catch (Exception exception)
{
receivers.Add("ERRCV");
}
}
}
}
您的问题从这里开始:
task.Wait();
You're blocking on async code,这会导致您陷入 僵局。
你想要:
private async void Button_Click(object sender, RoutedEventArgs e)
{
PluginUDP pudp = new PluginUDP();
string[] result = await pudp.scan("asf");
foreach (string s in result)
output.Text += s + "\r\n";
}
你还想做:
await Task.Delay(1000);
而不是:
Task.Delay(1000).Wait();