liu*_*uda 2 c# events multithreading
我想要达到的目标与标题相同.在我的问题中,我的主线程中有一个数据列表,我希望主线程触发一个事件,子线程可以处理该事件以使用数据列表.无论如何在C#中做到这一点?
我首先想到的方法是让子线程不断检查数据列表.但我想通过让主线程通知子线程,我可以节省让子线程在后台不断运行的开销.
你应该在这里使用生产者 - 消费者模式.父线程将充当生产者,子线程将充当消费者.父母将生成数据并以这样的方式发布它,以便通知孩子(无需轮询),以便它可以使用它.幸运的是,.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.
}
}
Run Code Online (Sandbox Code Playgroud)
因此,我们有一个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();
}
Run Code Online (Sandbox Code Playgroud)
如果要添加正常终止,可以使用任务取消机制来GetConsumingEnumerable
弹出枚举器.我没有说明这可以在这里,但它并不是非常困难,并且已经有很多例子.
归档时间: |
|
查看次数: |
596 次 |
最近记录: |