本文介绍了I&QUOT应该如何取消];在ConcurrentDictionary的AddOrUpdate?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过的MSDN文档和本博客我需要以下逻辑:

I've read the MSDN documents and this blog and I need the following logic:

对于 ConcurrentDictionary<字符串,布尔>

  1. 如果该字符串不存在,添加它,并确保我设置了布尔为同时加入
  2. 如果字符串确实存在,只是改变布尔以,如果它是假的。否则取消更新
  1. If the string doesn't exist, add it,and make sure I set the bool to True while adding
  2. If the string does exist, only change the bool to True if it's false. Otherwise cancel the update

我的用例

我有几个DNS域扫描恶意软件。有一个很好的可能性,那就是在列表重复我检索实时。我收到的小于或等于100批次的DNS域的列表,而且会有超过10,000的域进行扫​​描。

I have several DNS Domains to scan for malware. There is a good likelihood that there will be duplicates in the list that I retrieve in realtime. I receive the list of DNS Domains in batches of 100 or less, and there will be over 10,000 domains to scan.

我只想每10000域迭代扫描DNS主机一次。 A 布尔==真意味着它正在扫描之前,我去任何进一步的,我应该取消任务。 A 布尔==假或没有输入意味着我要立即更新条目布尔==真或创建一个新的进入ASAP项目。

I only want to scan a DNS host once per iteration of 10,000 domains. A bool == true means it's currently being scanned and I should cancel the task before I go any further. A bool == false or no entry means I should immediately update the entry as bool==true or create a new entry ASAP.

记住...

AddOrUpdate将分别从.NET4的TPL许多独立的线程调用。每一个线程需要决定是否需要工作在字典的中提到的值键 ...或者继续下一个。只有一个钥匙应该永远有工作做吧。

AddOrUpdate will be called independently from many independent threads in .NET4's TPL. Each thread needs to decide if it needs to work on the value mentioned in Dictionary's key... or proceed to the next one. Only one "key" should ever have work done to it.

我要发信号给调用线程的更新是成功还是失败。此外按照这个答案的似乎AddOrUpdate的功能将被调用多次。我想,这可能意味着我打电话线程将被混淆,取消对工作还是继续吧。 (记住只有一个线程可以积极制定

I need to signal to the calling thread that the update succeeded or failed. In addition according to this answer it seems that AddOrUpdate's functions will be called many times. I think this may mean my calling threads will be confused as to cancel work on key or to continue it. (remember only one thread can be actively working on key

并发更新的例子,可能会混淆调用线程

Example of concurrent updates that may confuse the calling thread

ConcurrentDictionary<int, string> numbers = new ConcurrentDictionary<int, string>();
Parallel.For(0, 10, x =>
{
    numbers.AddOrUpdate(1,
        i =>
        {
            Console.WriteLine("addValueFactory has been called");
            return i.ToString();
        },
        (i, s) =>
        {
            Console.WriteLine("updateValueFactory has been called");
            return i.ToString();
        });
});

输出

addValueFactory has been called
addValueFactory has been called
addValueFactory has been called
addValueFactory has been called
updateValueFactory has been called
updateValueFactory has been called
updateValueFactory has been called
updateValueFactory has been called
updateValueFactory has been called
updateValueFactory has been called
updateValueFactory has been called
updateValueFactory has been called
updateValueFactory has been called

问题

我应该如何添加此取消更新功能AddOrUpdate?

How should I add this "cancel update" functionality to AddOrUpdate?

推荐答案

如果我理解你想要达到什么样的,我不认为你可以使用 ConcurrentDictionary&LT;字符串,布尔&GT; 这一点。

If I understand what you're trying to achieve, I don't think you can use a ConcurrentDictionary<string, bool> for this.

一种可能的解决办法是具有一个封装一个给定主机的扫描一类:

One possible solution would be to have a class that encapsulates the scanning of a given host:

public class Scanner
{
    private static _syncRoot = new object();

    public Scanner(string host)
    {
        Host = host;
        StartScanning();
    }

    public string Host {get; private set; }

    public bool IsScanning {get; private set; }

    public void StartScanning()
    {
        lock(_syncRoot)
        {
            if (!IsScanning)
            {
                IsScanning = true;
                // Start scanning Host asynchronously
                ...
            }
        }
    }

    private void EndScanning()
    {
        // Called when asynchronous scanning has completed
        IsScanning = false;
    }
}

然后一个字典 ConcurrentDictionary&LT;字符串,懒&LT;扫描仪&GT;&GT;

您会使用它,如下所示:

You would use it as follows:

Scanner s = dictionary.GetOrAdd(host, new Lazy<Scanner>(() => new Scanner(host));
s.StartScanning();

延迟&LT;扫描仪&GT; 实例将使用默认的 LazyThreadSafetyMode.ExecutionAndPublication 模式,这意味着只有一个线程永远不会调用工厂委托实例化一个扫描器对于一个给定的主机。

The Lazy<Scanner> instance will use the default LazyThreadSafetyMode.ExecutionAndPublication mode, which means that only one thread will ever call the factory delegate to instantiate a Scanner for a given hosts.

这是我对你的问题的理解,它看起来对我来说,这是你想要达到的目的,即不扫描同一台主机不止一次。

From my understanding of your question, it looks to me like this is what you are trying to achieve, i.e. don't scan the same host more than once.

这篇关于I&QUOT应该如何取消];在ConcurrentDictionary的AddOrUpdate?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 15:12