我有一个用于进行蓝牙通信的课程,为了论证,我们说它看起来像这样:
class Bluetooth
{
public delegate void ByteFunc (byte[] packet);
public event ByteFunc OnPacketSending;
public event ByteFunc OnPacketReceived;
public void SendPackets(List<byte[]> packets)
{
foreach (byte[] packet in packets)
{
OnPacketSending?.Invoke(packet);
Bluetooth_Send(packet); // Pseudo-code, takes a few more calls than this
}
}
}
问题是事件通常是同步的(对吗?)所以如果我添加这样的事件处理程序:
Bluetooth.OnPacketSending += (packet) => RedrawTheEntireScreenAndAllKindsOfStuff(packet);
现在我在UI线程中调用SendPackets(),我的蓝牙通信速度变慢,因为所有的UI内容都在发生而不是蓝牙。
编译器不会让我说
public async event ByteFunc OnPacketSending
或
await OnPacketSending?.Invoke(packet)
我无法使用Control.BeginInvoke(),因为我不知道事件处理程序是否在控件中。
我在网上看到的大多数例子都把事件处理程序的责任放在异步做事上,我宁愿能够强制执行它。
是否足够/建议做一些简单的事情:
Task.Factory.StartNew (() => OnPacketSending?.Invoke (packet));
这是否使用线程池或类似方法来避免淹没可怜的移动设备?
答案 0 :(得分:0)
尝试使用BackgroundWorker。基本上,你启动一个方法然后它会在它完成时引发一个事件。
https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx
如果要等待,可以使用TaskCompletionSource。
答案 1 :(得分:0)
您可以做的是创建一个返回任务的delagate。 然后你可以使用这个委托作为Eventhandler并等待它。
public delegate Task MyDelegate();
public event MyDelegate MyEvent;
并像这样调用它:
await MyEvent?.Invoke();