我有一个同步问题,我有一个生成数据并将数据放入列表的线程。 我有其他线程需要采样“当前最新值”或“等待新数据,然后获取最新值”。
我生成数据的类大致如下所示:
public class GeneratingThread
{
public delegate void Callback();
public event EventHandler DataChanged;
private List<int> dataPayload = new List<int>();
/* other functions */
public int GetLastData()
{
/* synchronization */
return dataPayload.Last();
}
private void AsyncDataSampler(int data) /* Generates data in intervals of ~1ms */
{
/* synchronization */
dataPayload.Add(data);
if (DataChanged != null)
DataChanged(this, EventArgs.Empty);
}
}
消费数据的类如下所示:
public class ConsumingThread
{
int WaitForMeasurement(AsyncThread otherThread)
{
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
EventHandler waitForEvent = (Object sender, EventArgs args) => autoResetEvent.Set();
otherThread.DataChanged += waitForEvent;
autoResetEvent.WaitOne();
otherThread.DataChanged -= waitForEvent;
/* do something with the data */
return otherThread.GetLastData();
}
}
- 这是执行这些任务的最佳方式吗?等待通过设置 AutoResetEvent 的 EventHandler 事件可用的数据?
- 我是否需要在
otherThread.DataChanged
处理程序中显式添加和删除EventHandler waitForEvent
?或者对象在删除/清理时是否将其自身从事件列表中删除? - 是否有库提供的方法可以为我完成所有这些工作?还是有更多的
C#
方式来做这些事情?
(请注意,我的背景是嵌入式 C++,并且了解一些 C#)如果 C# 看起来有点糟糕,请原谅我。在这里学习 ;-)
最佳答案
因为(评论)你实际上需要所有的数据,而不仅仅是最新的;这似乎非常适合 Channel<T>
; Channel<T>
明确设计用于完全异步(async
/await
)生产者/消费者场景,并具有针对有界与无界、线程模型、多个与单个生产者/消费者以及要执行的操作的配置选项当有界 channel 已满(延迟、丢弃旧的、丢弃新的等)时。
所以基本上:考虑使用 Channel<T>
;它在 nuget 上可用,包括对 netstandard1.3 和 net46 的支持:https://www.nuget.org/packages/System.Threading.Channels/
这里有一个很好的使用概述:https://www.stevejgordon.co.uk/an-introduction-to-system-threading-channels
关于c# - 异步等待数据改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59029566/