Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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# 如何等待值添加到ConcurrentDictionary或发生超时?_C#_Multithreading_Data Structures - Fatal编程技术网

C# 如何等待值添加到ConcurrentDictionary或发生超时?

C# 如何等待值添加到ConcurrentDictionary或发生超时?,c#,multithreading,data-structures,C#,Multithreading,Data Structures,我有一个任务,应该等到一个值被添加到ConcurrentDictionary之后再执行。如果增加了值,它应该停止等待并继续工作。如果发生超时(例如5秒),它也应该停止等待 该值应该由另一个线程/任务添加到ConcurrentDictionary中,但是,由于代码的性质,我不希望线程彼此通信 我应该如何(用C#)实现这一点 顺便说一句,我使用的是任务,而不是大部分线程,因此我不确定当前线程上的Thread.Sleep或其他方法是否是一个好的决定,因为它可能会休眠使用相同线程的其他任务,并导致随机问

我有一个任务,应该等到一个值被添加到ConcurrentDictionary之后再执行。如果增加了值,它应该停止等待并继续工作。如果发生超时(例如5秒),它也应该停止等待

该值应该由另一个线程/任务添加到ConcurrentDictionary中,但是,由于代码的性质,我不希望线程彼此通信

我应该如何(用C#)实现这一点


顺便说一句,我使用的是任务,而不是大部分线程,因此我不确定当前线程上的Thread.Sleep或其他方法是否是一个好的决定,因为它可能会休眠使用相同线程的其他任务,并导致随机问题。

我不相信
ConcurrentDictionary
为类似的事情提供了任何挂钩

您可以包装或从
ConcurrentDictionary
派生来提供这一点,但这样做会让我感到紧张


低技术的替代方法是简单地轮询循环,检查然后睡觉,直到找到正确的值或超时。从效率的角度来看,这远不是很好,但如果它不给您带来任何其他问题,它可能是最简单的方法。

这就是睡眠轮询的工作原理。又快又脏。:)

System.Collections.Concurrent.ConcurrentDictionary dic=新系统.Collections.Concurrent.ConcurrentDictionary();
int timeoutCount=0;
bool-hastinmedout=false;
而(!dic.ContainsKey(“您正在寻找的钥匙”))
{
//5分钟已经过去了
如果(超时计数>=10)
{
Hastinmedout=正确;
打破
}
//30秒的睡眠时间或任何你想要的投票时间
系统。线程。线程。睡眠(30000);
timeoutCount++;
}
如有(请退出)
{
//TODO:超时代码
}
其他的
{
//TODO:已添加密钥
}
我认为“等待”一个元素被添加到集合中通常是一件坏事。通常,这样做意味着一个线程会被阻塞一段时间。如果可能的话,你就必须处理超时问题。如果无法检测超时,则必须处理中止线程以中止等待(您永远不希望陷入线程被无限期阻塞的情况),例如取消


ConcurrentDictionary
本身是线程安全的;但这并不能使所有使用
concurrentdirectionary
的代码都是线程安全的。在使用
ConcurrentDictionary
对象时,仍需要考虑特定于应用程序的线程安全要求
ConcurrentDictionary
不可能实现这些类型的东西。当一个值被添加到字典中时,该怎么办也非常相似——在新的值添加时等待或通知外部代码的开销会导致
ConcurrentDictionary
的所有用法都变慢,甚至那些不需要等待或不需要通知的用法也会变慢——因此类似的事情没有实现。一个应用程序添加了一个值并且需要被通知已经添加了一个值这一事实可能非常罕见(从字典的角度来看,为什么它会告诉您刚刚添加了一个值…)。因此,这种特定于应用程序的事情通常是在应用程序级别完成的。i、 使用并发字典的事实是一种巧合,您的应用程序会通知其他线程另一个线程做了他们需要知道的事情。这可能意味着包装会通过调用
ManualResetEventSlim.Reset
/
Set
添加到字典实例中,并且可以使用
ManualResetEventSlim.wait
覆盖等待。或者,也可以简单地编写一个事件,每当向字典中添加值时就会引发该事件。

非常感谢。顺便说一句,你确定这不会造成麻烦,因为我使用的是任务而不是线程?一个线程可以处理多个任务。等待和添加任务不可能都在同一个线程上,因此都会导致死锁?那么你就有了如何处理被阻塞30秒的线程的问题。是一个关于任务和线程的好链接。您可以将此代码添加到新线程中。你不想使用新线程有什么原因吗?我读了那个链接,但它没有解决我的问题。最后给出的示例假定该值在任务完成执行后返回。在我的例子中,另一个任务在将该值添加到字典后仍将继续工作,我提到我不想通过在它们之间进行线程/任务间通信来使代码复杂化。我只想通过任务来做每件事,因为它们比线程更高效,在我的情况下,我可能需要几十个/数百个任务,将它们作为单独的线程来做,并且自己管理它们将非常复杂。是的,围绕它可能会导致额外的麻烦,我希望避免。我担心轮询循环,因为我正在使用任务,如果生产者和消费者任务位于同一个线程上,则休眠线程可能会导致生产者和消费者任务同时休眠,从而导致死锁:/@xander:Polling导致的死锁不会比提供的等待类型多。在这两种情况下,你只有两个睡眠任务。这怎么会是死锁?我不确定这是否会是死锁,但如果两者都处于休眠状态,那么生产者将无法将值放入字典中,并且它将超时?另外,我不希望有几个任务在可能很长(~5秒+)的超时时间内处于休眠状态。我认为最理想的是像task.Sleep这样的东西,它不会影响其他正在运行的任务。@xander:听起来你需要更仔细地考虑你的需求。这怎么可能避免他们两人同时等待呢?想象一下你有一个完美的方法
System.Collections.Concurrent.ConcurrentDictionary<string,string> dic = new System.Collections.Concurrent.ConcurrentDictionary<string,string>();

int timeoutCount = 0;
bool hasTimedOut = false;
while (!dic.ContainsKey("KeyYouAreLookingFor"))
{
    //5 minutes has expired
    if (timeoutCount >= 10)
    {
        hasTimedOut = true;
        break;
    }

    //30 second sleep or whatever you want your poll time to be
    System.Threading.Thread.Sleep(30000);
    timeoutCount++;
}

if (hasTimedOut)
{
    //TODO: timeout code
}
else
{
    //TODO: Key has been added
}