c# Android - ISurfaceTextureListener 线程中断然后在 activity 关闭时恢复
c# Android - ISurfaceTextureListener thread interrupted then resumed when activity closed
我有一个 activity(带有 ISurfaceTextureListener)和一个异步 OnSurfaceTextureUpdated 方法,我在其中调用异步 SendPixel 方法:
public async void OnSurfaceTextureUpdated(SurfaceTexture surface)
{
bool sendPixel = false;
[...]
if (Settings.Pixel.period >= 0)
{
if (stopWatch.ElapsedMilliseconds >= Settings.Pixel.nextSending)
{
if (Settings.Pixel.period > 0)
Settings.Pixel.nextSending += Settings.Pixel.period * ((int)((stopWatch.ElapsedMilliseconds - Settings.Pixel.nextSending) / Settings.Pixel.period) + 1);
sendPixel = true;
}
}
[...]
if (sendPixel)
await SendPixel();
}
这是异步 SendPixel 方法:
async Task SendPixel()
{
try
{
if (Ev3Messaging.IsConnected())
{
Color color = new Color(bm.GetPixel(Settings.Camera.viewport.X_VpToCv(Settings.Pixel.x), Settings.Camera.viewport.X_VpToCv(Settings.Pixel.y)));
Ev3Messaging.AddNumberMessage("MC_Hue", color.GetHue());
Ev3Messaging.AddNumberMessage("MC_Brightness", color.GetBrightness());
Console.WriteLine("SendPixel");
await Ev3Messaging.SendMessages();
Console.WriteLine("SendPixelEnd");
}
}
catch (Exception ex)
{
Console.WriteLine("Error SendPixel: " + ex.Message);
}
}
ISurfaceTextureListener读取一个视频流,然后多次调用SendPixel方法。
问题是控制台很好地显示 "SendPixel",但不显示 "SendPixelEnd",并且没有抛出任何错误。
之后,当我关闭 activity 时,每个缺失的 "SendPixelEnd" 都会显示出来。
编辑:EV3Messaging.SendMessages 发送在前几行中添加的消息(通过蓝牙):
static List<byte> btMessage = new List<byte>();
static public async Task SendMessages()
{
if (_socket != null)
await _socket.OutputStream.WriteAsync(btMessage.ToArray(), 0, btMessage.Count);
}
为什么会发生这种情况,我该如何解决?
提前致谢。
PS: 抱歉我的英语不好^^
已解决:我每次发送数据时都忘记清除 btMessage 列表,这导致了这种奇怪的行为。这个问题也可能是因为从蓝牙设备接收数据的方式不对。
然后 SendMessages 方法变为:
static public async Task SendMessages()
{
if (_socket != null)
await _socket.OutputStream.WriteAsync(btMessage.ToArray(), 0, btMessage.Count);
btMessage.Clear();
}
因为我每次添加消息时,都会将新帧添加到 btMessage 列表的末尾。
此外,要获取传入消息,我使用此代码:
public static void InputMessagesManager(Action<BtMessage> incomingMessageEvent)
{
_tokenSource = new CancellationTokenSource();
Task t = Task.Factory.StartNew(async () =>
{
Stream inputStream = _socket.InputStream;
while (!_tokenSource.IsCancellationRequested)
{
if (inputStream == null)
inputStream = _socket.InputStream;
if (inputStream != null && inputStream.CanRead)
{
await inputStream.ReadAsync(_sizeBuffer, 0, _sizeBuffer.Length);
short size = (short)(_sizeBuffer[0] | _sizeBuffer[1] << 8);
if (size != 0)
{
byte[] frame = new byte[size];
await inputStream.ReadAsync(frame, 0, frame.Length);
BtMessage btMes = new BtMessage(frame);
incomingMessageEvent(btMes);
Console.WriteLine("Received: " + btMes.name + " -> " + btMes.getValueAsNumber());
}
}
}
}, _tokenSource2.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current);
}
我有一个 activity(带有 ISurfaceTextureListener)和一个异步 OnSurfaceTextureUpdated 方法,我在其中调用异步 SendPixel 方法:
public async void OnSurfaceTextureUpdated(SurfaceTexture surface)
{
bool sendPixel = false;
[...]
if (Settings.Pixel.period >= 0)
{
if (stopWatch.ElapsedMilliseconds >= Settings.Pixel.nextSending)
{
if (Settings.Pixel.period > 0)
Settings.Pixel.nextSending += Settings.Pixel.period * ((int)((stopWatch.ElapsedMilliseconds - Settings.Pixel.nextSending) / Settings.Pixel.period) + 1);
sendPixel = true;
}
}
[...]
if (sendPixel)
await SendPixel();
}
这是异步 SendPixel 方法:
async Task SendPixel()
{
try
{
if (Ev3Messaging.IsConnected())
{
Color color = new Color(bm.GetPixel(Settings.Camera.viewport.X_VpToCv(Settings.Pixel.x), Settings.Camera.viewport.X_VpToCv(Settings.Pixel.y)));
Ev3Messaging.AddNumberMessage("MC_Hue", color.GetHue());
Ev3Messaging.AddNumberMessage("MC_Brightness", color.GetBrightness());
Console.WriteLine("SendPixel");
await Ev3Messaging.SendMessages();
Console.WriteLine("SendPixelEnd");
}
}
catch (Exception ex)
{
Console.WriteLine("Error SendPixel: " + ex.Message);
}
}
ISurfaceTextureListener读取一个视频流,然后多次调用SendPixel方法。 问题是控制台很好地显示 "SendPixel",但不显示 "SendPixelEnd",并且没有抛出任何错误。 之后,当我关闭 activity 时,每个缺失的 "SendPixelEnd" 都会显示出来。
编辑:EV3Messaging.SendMessages 发送在前几行中添加的消息(通过蓝牙):
static List<byte> btMessage = new List<byte>();
static public async Task SendMessages()
{
if (_socket != null)
await _socket.OutputStream.WriteAsync(btMessage.ToArray(), 0, btMessage.Count);
}
为什么会发生这种情况,我该如何解决?
提前致谢。
PS: 抱歉我的英语不好^^
已解决:我每次发送数据时都忘记清除 btMessage 列表,这导致了这种奇怪的行为。这个问题也可能是因为从蓝牙设备接收数据的方式不对。
然后 SendMessages 方法变为:
static public async Task SendMessages()
{
if (_socket != null)
await _socket.OutputStream.WriteAsync(btMessage.ToArray(), 0, btMessage.Count);
btMessage.Clear();
}
因为我每次添加消息时,都会将新帧添加到 btMessage 列表的末尾。
此外,要获取传入消息,我使用此代码:
public static void InputMessagesManager(Action<BtMessage> incomingMessageEvent)
{
_tokenSource = new CancellationTokenSource();
Task t = Task.Factory.StartNew(async () =>
{
Stream inputStream = _socket.InputStream;
while (!_tokenSource.IsCancellationRequested)
{
if (inputStream == null)
inputStream = _socket.InputStream;
if (inputStream != null && inputStream.CanRead)
{
await inputStream.ReadAsync(_sizeBuffer, 0, _sizeBuffer.Length);
short size = (short)(_sizeBuffer[0] | _sizeBuffer[1] << 8);
if (size != 0)
{
byte[] frame = new byte[size];
await inputStream.ReadAsync(frame, 0, frame.Length);
BtMessage btMes = new BtMessage(frame);
incomingMessageEvent(btMes);
Console.WriteLine("Received: " + btMes.name + " -> " + btMes.getValueAsNumber());
}
}
}
}, _tokenSource2.Token, TaskCreationOptions.LongRunning, TaskScheduler.Current);
}