সমকালীন অভিধানের সঠিক ব্যবহার


84

আমি কি ভেবেছি সঠিক, এটি একটি সমকালীন অভিধানের সঠিক ব্যবহার

private ConcurrentDictionary<int,long> myDic = new ConcurrentDictionary<int,long>();

//Main thread at program startup

for(int i = 0; i < 4; i++)
{
  myDic.Add(i, 0);
}

//Seperate threads use this to update a value

myDic[InputID] = newLongValue;

আমার কোনও লক ইত্যাদি নেই এবং কেবল অভিধানে মানটি আপডেট করছি যদিও একাধিক থ্রেড একই রকম চেষ্টা করে।


4
এটি নির্ভর করে - newLongValueএর আগের মানটির উপর নির্ভর করে myDic[InputID]?
ড্যামিয়েন_এ_বিশ্বাসীরা

4
আপনার myDic[InputID]জাতির অবস্থার জন্য সরাসরি কী দ্বারা অ্যাক্সেস করা উচিত । আপনার চেষ্টা করা উচিতGetOrAdd
অলিভিয়ার আলবার্টিনি

4
@ অলিভিয়ার অ্যালবার্টিনি, আমি মনে করি না যে myDic[InputID]এটি যখন কোনও মূল্য হিসাবে ব্যবহার করা হয় তখন কোনও সমস্যা হয় GetOrAddএটি কোনও সঠিক প্রতিস্থাপন নয় যেহেতু এটির সাথে কেবলমাত্র মূল্য উপস্থিত না থাকলে যুক্ত হয়। পরিবর্তে আমরা AddOrUpdateঅভিধানে একই মান যুক্ত / আপডেট করতে ব্যবহার করতে পারি ।
যতীন সংঘভি 0

উত্তর:


75

এটি থ্রেড-সেফ দ্বারা আপনি কী বোঝাতে চান তার উপর নির্ভর করে।

এমএসডিএন থেকে - কীভাবে: সমবর্তী অভিধান থেকে আইটেমগুলি যুক্ত এবং সরান :

ConcurrentDictionary<TKey, TValue>মাল্টিথ্রেডেড দৃশ্যের জন্য ডিজাইন করা হয়েছে। সংগ্রহ থেকে আইটেম যুক্ত করতে বা সরাতে আপনাকে আপনার কোডে লক ব্যবহার করতে হবে না। তবে, একটি থ্রেডের পক্ষে সর্বদা মান পুনরুদ্ধার করা সম্ভব হয় এবং অন্য থ্রেডে একই কীটিকে একটি নতুন মান দিয়ে তাৎক্ষণিকভাবে সংগ্রহ আপডেট করা সম্ভব update

সুতরাং, অভিধানে কোনও আইটেমের মান সম্পর্কে অসামঞ্জস্যিত দৃষ্টিভঙ্গি পাওয়া সম্ভব ।


4
এটি একটি আকর্ষণীয় বিষয়! আপনি কি এখনও সেই দৃশ্যে একটি লক ব্যবহার করবেন?
জন

@ জোন - এটি আপনার অ্যাপ্লিকেশন এবং এটি ঠিক আছে কি না তা নির্ভর করে। তবে আমি বলব যে আপনি যদি আইটেমগুলির বিষয়ে ধারাবাহিক মতামত চান তবে আপনার কোনও পঠন এবং তালিকার একটি তালিকে একটি লকে মোড়ানো দরকার।
ওদে

12
আমি মনে করি এটি ডক বলে না। অসামঞ্জস্যতার সাথে ভিউটি যা রয়েছে তার সাথে সম্পর্কযুক্ত, যদি ভিউটি কেবলমাত্র মান হয় তবে এটি পুরোপুরি সামঞ্জস্যপূর্ণ। যতক্ষণ আপনি কোনও কীটির মান পাবেন ততক্ষণ অভিধানে কীটির মান পরিবর্তন হতে পারে। এটি ডেটটাইম.নো মানের মতোই বেমানান।
জর্জ মাভ্রিতসাকিস

4

এটি খুঁজে বের করার সর্বোত্তম উপায় হ'ল এমএসডিএন ডকুমেন্টেশন check

সমকালীন অভিধানের জন্য পৃষ্ঠাটি হ'ল http://msdn.microsoft.com/en-us/library/dd287191.aspx

থ্রেড সুরক্ষা বিভাগের অধীনে এটি উল্লেখ করা হয়েছে "সমকালীন অভিধানের সমস্ত পাবলিক এবং সুরক্ষিত সদস্য (অফ কে, টিভিয়ালিউ) থ্রেড-সেফ এবং একাধিক থ্রেড থেকে একসাথে ব্যবহার করা যেতে পারে।"

সুতরাং সম্মতিযুক্ত দৃষ্টিকোণ থেকে আপনি ঠিক আছেন।


2

হ্যাঁ তুমিই ঠিক.

এটি এবং অন্য থ্রেডে পরিবর্তন করার সময় অভিধানকে এক থ্রেডে অঙ্ক করার সম্ভাবনা সেই শ্রেণীর পক্ষে অস্তিত্বের একমাত্র উপায় means


10
আমি যেটি যুক্ত করতে চাই তা হ'ল এখানে এবং কখন কীভাবে ব্যবহার করবেন তার সহায়ক তথ্য ConcurrentDictionary
alex.b

1

এটি নির্ভর করে, আমার ক্ষেত্রে আমি এই পদ্ধতিটি ব্যবহার করতে পছন্দ করি।

ConcurrentDictionary<TKey, TValue>.AddOrUpdate Method (TKey, Func<TKey, TValue>, Func<TKey, TValue, TValue>);

পদ্ধতি ব্যবহারের বিশদগুলির জন্য এমএসডিএন লাইব্রেরি দেখুন ।

নমুনা ব্যবহার:

results.AddOrUpdate(
  Id,
  id => new DbResult() {
     Id = id,
     Value = row.Value,
     Rank = 1
  },
  (id, v) =>
  {
     v.Rank++;
     return v;
  });

4
এফওয়াইআই: "আপনি যখন কোনও ভ্যালু ফ্যাক্টরি পদ্ধতি সরবরাহ করেন (getOrAdd এবং AddOrUpdate পদ্ধতিতে), এটি আসলে চলতে পারে এবং এর ফলাফল পরে বাতিল করা যেতে পারে (কারণ অন্য কোনও থ্রেড রেস জিতেছিল)। এখানে আরও তথ্য: arbel.net/2013/02/03/…
কেরেমিসপিরলি

হ্যাঁ, আপনি ঠিকই বলেছেন, যেমনটি মন্তব্য বিভাগে উল্লেখ করা হয়েছে "আপনি যদি বিভিন্ন থ্রেডে একযোগে অ্যাডআরআপটেট কল করেন তবে অ্যাডভ্যালুফ্যাক্টরিটিকে একাধিকবার ডাকা যেতে পারে, তবে এর মূল / মান জুটি প্রতিটি কলের জন্য অভিধানে যুক্ত করা যাবে না।" সুতরাং আপনাকে নিশ্চিত হতে হবে যে আপনি একাধিক ধ্রুবক অবজেক্ট তৈরি করছেন না।
ওনুর

এবং যদি আপনার সামগ্রীতে আপডেট করার প্রয়োজন হয়, সম্পূর্ণরূপে সঞ্চিত বস্তুটি পরিবর্তন না করা, উদাহরণস্বরূপ পূর্ববর্তী যুক্ত হওয়া সামগ্রীর সম্পত্তি পরিবর্তন করার জন্য, এই পদ্ধতিটি দরকারী, অন্যথায় আপনাকে লকস বা অন্যান্য সিঙ্ক্রোনাইজেশন পদ্ধতি ব্যবহার করতে হবে।
অনুর

1

কেবলমাত্র একটি দ্রষ্টব্য: একটি লিনিয়ার লুপের সাহায্যে একটি সাম্প্রতিক ডিসিটোনারি অবজেক্টটি যুক্তিসঙ্গত করা যায় না , এটিকে নিম্নগতিযুক্ত করে তোলে। সর্বোত্তম বিকল্প হ'ল মাইক্রোসফ্ট ডকুমেন্টেশনের সুপারিশগুলি অনুসরণ করা, যেমন ওডে সমান্তরালতা ব্যবহার করে উল্লিখিত , নীচের উদাহরণ অনুসারে:

Parallel.For(0, 4, i => 
{
   myDic.TryAdd(i, 0);
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.