Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 防止线程不必要地执行代价高昂的任务_C#_Multithreading_Concurrency_Locking - Fatal编程技术网

C# 防止线程不必要地执行代价高昂的任务

C# 防止线程不必要地执行代价高昂的任务,c#,multithreading,concurrency,locking,C#,Multithreading,Concurrency,Locking,我希望通过以下方式保护对资源的访问: 除了在更新期间(如果更新不是原子的),所有线程都可以并发读取 只有一个线程可以被分配更新任务,直到下一次 需要更新 这可能看起来像是一个简单的问题,即使用适当的锁,或者可能使所有操作原子化,但我认为这不是问题所在 如果我只是有一个用于更新的写锁(即ReaderWriterLockSlim),或者使用非锁定代码,那么没有什么可以阻止多个线程运行更新过程(或者排队执行)。如果我在检查资源是否需要更新之前使用锁定来阻止线程,那么它们不能并发执行,但可以有效地序

我希望通过以下方式保护对资源的访问:

  • 除了在更新期间(如果更新不是原子的),所有线程都可以并发读取
  • 只有一个线程可以被分配更新任务,直到下一次 需要更新
这可能看起来像是一个简单的问题,即使用适当的
锁,或者可能使所有操作原子化,但我认为这不是问题所在

如果我只是有一个用于更新的写锁(即ReaderWriterLockSlim
),或者使用非锁定代码,那么没有什么可以阻止多个线程运行更新过程(或者排队执行)。如果我在检查资源是否需要更新之前使用锁定来阻止线程,那么它们不能并发执行,但可以有效地序列化

我可以让特定的线程执行资源的所有检查和更新,并利用类似于
ManualResetEvent
的方法将其他读取线程搁置,直到更新完成。(或者,如果更新是作为一个原子操作实现的,只需满足于使用特定的更新线程即可。)


然而,我不确定最佳实践,我想问一下您是否认为这些要求可以用更少的努力来满足,或者我的任何假设都有偏差。

我想您正在寻找一个
ReaderWriterLockSlim
。使用独占锁定模式进行写入。

我知道ReaderWriterLockSlim类,但我无法找到一种使用模式,防止线程排队执行不必要的更新,即使使用独占锁定模式进行写入。这就是我在我的问题中试图解释的——“如果我只是有一个用于更新的写锁[…],没有什么可以阻止多个线程运行更新过程(或排队执行更新过程)”。我忽略了这一点。尝试在零超时的情况下获取写锁,并在锁忙的情况下跳过更新。我明白你的想法,但该线程仍然需要返回一个值。因此,我需要返回并重试,可能会多次进入“更新模式”,直到“第一个线程”完成对资源的更新。我觉得有点不干净。还是我弄错了?我明白问题所在。将可写资源设为惰性资源。一个编写器可以在写锁下创建一个新的延迟并立即退出。然后,任何先到的线程都会迫使懒惰的线程运行。所有线程在完成时拾取相同的值。有趣。我不会想到使用
Lazy
类来实现这一点。我得试一试。请你用一段代码来更新你的答案,这样如果我接受这个答案,其他人可能会更容易理解为什么?奇怪的问题。如果您的线程非常难以控制,以至于您无法在代码中确保只启动执行更新一次的线程,那么您也无法保证它们的行为良好并正确使用RWL。添加额外的锁只会导致死锁。这从来都不是一个真正的问题,不要让它成为一个问题。为什么你会假设对访问实例的线程拥有控制权?请随意解释一下你是如何确定“这从来不是一个真正的问题”的。这似乎是一个奇怪的评论。