如何使用自定义的锁到字符串值

本文关键字:字符串 何使用 自定义 | 更新日期: 2023-09-27 18:33:25

我不确定是使用互斥还是信号量或其他工具。

这是我的方案:在多线程环境中,某些事件会导致映像写入磁盘。此图像在事件处理程序中生成。

问题是,事件 A 导致图像 A .png正在写入,事件 B 导致名为 B.png 的图像。

如果这些事件同时发生,则可以保存映像(尽管显然磁盘不能很好地处理并行写入(,但这是一个有效的方案。

但有时事件 A 会多次触发。这也是有效的,但调用图像。保存相同的文件名会导致通用 GDI 错误。

如何锁定 .使用工具保存(...(调用而不锁定每个线程(如使用lock关键字(

我想到了一个手工制作的解决方案,其中处理程序将文件名写入查找表,然后写入文件。其他处理程序需要检查查找,然后执行一些 Thread.Sleep 或类似操作。但这看起来确实像是资源锁定的幼稚方法。

对于这种锁定"虚拟"资源的自定义锁,是否有正确的方法?(虚拟,因为它在锁定时可能不存在(。

更新和编辑:图像生成执行一些数字处理,因此包装在任务中。典型的方案是始终同时创建多个映像以利用 Thread.Pool。我知道作业队列可以解决问题,但它会删除并行执行。如果我手动将作业分发到 n 线程(这意味着编写我自己的池,对吧?我仍然会遇到两个线程可以尝试写入同一个文件的问题。

事件

源是不可靠的,因此它可能会对同一个文件多次调用写入操作,但实际上只要一个"映像 A"生成正在工作或尚未启动,就可以忽略第二个、第三个或任何事件处理。

如何使用自定义的锁到字符串值

创建一个Queue<MyImageWriteTaskClass>. 生成一个线程,该线程检查队列是否已填充,如果是,则逐个取消队列内容的排队,将映像写入磁盘,直到队列为空,线程恢复等待,直到新项目已排队。触发事件时,只需将新MyImageWriteTaskClass排队即可。

假设您使用线程安全队列,则除了在出列和排队周围使用单个锁外,不需要其他锁定。如果硬件跟不上,或者有磁盘缓存,则可能需要限制磁盘保存操作。

或者,如果您想花哨并使用最新和最好的工具,您可以考虑使用 IObservable 并处理可观察的保存事件流。这还有一个额外的好处,即大大简化了诸如限制之类的非常花哨的机制。

补充马

可的答案:您可以使用BlockingCollection<T>类,它实现了生产者-消费者模式。请参阅文档的示例部分中ConsumingEnumerableDemo类。