-1

Now, in my project, I have to write the data from different ipaddresses into separate lists. I am having a problem in how I will record in what order.

The number of connections can be 500. The user can close and open connections as they wish. In case he closes the connection, no registration should be made for that list.

For example; The ip address 192.168.1.20 - 192.168.1.30 - 192.168.1.40 is three connections. I know from which ip address the data comes from but I cannot control which list I should write the data to.

I have 3 lists named Log_1 Log_2 Log_3. In case of opening the connection, I can record respectively. When he closes the 2nd connection and then reconnects, the queue will be shifted and this will make my administration difficult. How can I get out of this situation?

To summarize; I need to keep the data from each ip in separate lists. It must be able to support up to 500 connections.

I used "ConcurrentDictionary" but ConcurrentDictionary does not add when data comes from the same key. Is there an alternative? Or am I making a mistake somewhere.

My Code

ConcurrentDictionary<string, Queue<byte[]>> FullData = new ConcurrentDictionary<string, Queue<byte[]>>();

DataReceived Code

byte[] Data = e.Data;
        FullData.TryAdd(e.IpPort, Data);
Rekshino
  • 6,954
  • 2
  • 19
  • 44
  • 2
    You don't want to add the same key twice. When the key already exists you want to add something to the queue behind this existing key right? The code you showed us doesn't do that. – user743414 Dec 15 '20 at 06:58
  • Yes I want to do what you say. But I don't understand how to do it. If the key and e.IpPort are the same, I want that key to add above its value. –  Dec 15 '20 at 07:00
  • 1
    To add the value you have to get the Queue inside the dictionary by the key and then add your e.Data to that queue. – user743414 Dec 15 '20 at 07:02
  • How can I get the queue from the dictionary by key? –  Dec 15 '20 at 07:03

2 Answers2

1

You can access the Queue like this FullData[e.IpPort] and add the new value to your queue.

if (!FullData.ContainsKey(e.IpPort))
    FullData.TryAdd(e.IpPort, new ConcurrentQueue<byte[]>());

byte[] Data = e.Data;
        FullData[e.IpPort].Enqueue(Data);

You shoould also probably use ConcurrentQueue in a non thread safe context.

Athanasios Kataras
  • 25,191
  • 4
  • 32
  • 61
  • Thank you. Both of them work for me. Which one is required as an answer. I know it might be the only answer. –  Dec 15 '20 at 07:40
  • I really prefered the `GetOrAdd` flavor that Moho added, but seriously consider the `ConcurrentQueue` suggestion. – Athanasios Kataras Dec 15 '20 at 08:16
  • What exactly do you mean by unsafe? DataReceived is running in separate thread. –  Dec 15 '20 at 10:35
  • You have at least two threads working on the same queue. The one that adds the items, and the other that removes them. If you want to ensure thread safety for your FIFO operations, then you should use the ConcurrentQueue. – Athanasios Kataras Dec 15 '20 at 10:48
  • Check https://stackoverflow.com/questions/13416889/thread-safe-queue-enqueue-dequeue for an example issue. – Athanasios Kataras Dec 15 '20 at 10:51
  • 1
    Thank you so much. I would probably run into such a problem. It has been very good for me. –  Dec 15 '20 at 10:54
  • How can I access the data I have added in "new ConcurrentQueue ()"? I will put this data into a mathematical process. –  Dec 15 '20 at 11:10
  • The same way you would do with a normal queue, by calling Deque – Athanasios Kataras Dec 15 '20 at 11:10
  • There are more than one "ConcurrentQueue" in FullData. How is it possible to access each one separately? This is the first time "ConcurrentQueue" and "ConcurrentDictionary" so I have trouble understanding. Sorry. –  Dec 15 '20 at 11:25
  • By retrieving each individual queue from the dictionary using the key. – Athanasios Kataras Dec 15 '20 at 12:58
  • Check the latest edit, the fix is very simple. – Athanasios Kataras Dec 15 '20 at 12:59
  • I accessed data and keys using foreach. Thanks for be interested. –  Dec 15 '20 at 13:01
1

You want to add the Data to the Queue Keyed by e.IpPort. Use the FullData.GetOrAdd method to retrieve the queue. This will add a new queue (via supplied expression) to the dictionary if they key is not found:

var queue = FullData.GetOrAdd(e.IpPort, (key) => new Queue<byte[]>(...));

queue.Enqueue(Data);
Moho
  • 15,457
  • 1
  • 30
  • 31
  • Thank you. Both of them work for me. Which one is required as an answer. I know it might be the only answer. –  Dec 15 '20 at 07:40