gpt4 book ai didi

c# - 子线程处理父级引发的事件

转载 作者:行者123 更新时间:2023-11-30 19:41:50 28 4
gpt4 key购买 nike

我要实现的目标与标题相同。在我的问题中,我的主线程中有一个数据列表,我想让主线程触发一个可以由子线程处理的事件来使用数据列表。反正有没有用 C# 做的?

我首先想到的做法是让子线程不断检查数据列表。但我认为通过让主线程通知子线程,我可以节省让子线程在后台不断运行的开销。

最佳答案

您应该在这里使用生产者-消费者模式。父线程充当生产者,子线程充当消费者。 parent 将生产数据并以通知 child (无需轮询)的方式发布数据,以便 child 可以使用它。幸运的是,.NET 使用 BlockingCollection 类使这变得很容易。您的代码可能如下所示。

class Producer
{
private BlockingCollection<YourData> queue;

public Producer(BlockingCollection<YourData> q)
{
queue = q;
}

public void GenerateItems()
{
while (...)
{
YourData item = GenerateItem();
queue.Add(item);
}
}
}

class Consumer
{
public Consumer(BlockingCollection<YourData> queue)
{
Task.Factory.StartNew(
() =>
{
foreach (YourData item in queue.GetConsumingEnumerable())
{
ProcessItem(item);
}
), TaskCreationOptions.LongRunning);
}

private void ProcessItem(YourData item)
{
// Add logic to process each data item here.
}

}

所以我们有一个 Producer 类生成数据项并将它们添加到 BlockingCollection 和一个 Consumer 类删除这些数据项他们变得可用。 GetConsumingEnumerable 的行为类似于 Take,因为如果队列中没有任何内容,它会将调用方置于空闲状态。所以基本上调用线程不会进行任何类型的繁忙轮询(至少不是在琐碎的意义上),因此它是资源友好的。

这是一个如何将所有内容粘合在一起的示例。

public static void Main()
{
var queue = new BlockingCollection<YourData>();
var producer = new Producer(queue);
var consumer = new Consumer(queue);
producer.GenerateItems();
}

您可以使用 task cancellation mechanisms如果要添加正常终止,让 GetConsumingEnumerable 枚举器弹出。我没有在此处展示这是如何实现的,但这并不十分困难,并且已经有很多示例。

关于c# - 子线程处理父级引发的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18736771/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com