multithreading - C# ConcurrentDictionary vs. ManualResetEvent for Thread Control -
i have windows service uses system.threading.timer callback update endpoints so:
updateendpointtimer = new timer( new timercallback(updatesbendpoints), endpoint.statuses.online, endpointupdatefrequency, endpointupdatefrequency);
here update method looks like:
private void updatesbendpoints(object state) { ... using (var context = new testharnesscontext()) { var endpoints = context.endpoints.where(p => p.binding == endpoint.bindings.servicebus && p.state == endpoint.states.enabled && p.status != status).tolist(); foreach (var endpoint in endpoints) { //do stuff here } ... }
now timer uses threads threadpool fire callbacks, need measures command threads. 1 specific problem occurs when multiple threads can grab same endpoint db before first thread finishes work, , results in duplicate work done in foreach loop.
i know 2 possible solutions problem , wonder 1 improve , preferable use. solutions concurrentdictionary
, manualresetevent
.
in first case set within foreach loop ensure 1 thread @ time can operate on given endpoint:
if (endpointsinaction.tryadd(endpoint.id, endpoint.id) == false) // if here, thread has started work endpoint. return; ... //do stuff endpoint, 1 time done, remove id dictionary ... int id; endpointsinaction.tryremove(endpoint.id, out id);
in sec case, command threads so:
protected manualresetevent pubisbeingcreated { get; set; } protected manualresetevent subisbeingcreated { get; set; } ... this.pubisbeingcreated = new manualresetevent(true); this.subisbeingcreated = new manualresetevent(true); ... foreach (var endpoint in endpoints) { if (!this.pubisbeingcreated.waitone(0)) // if here, thread has started work endpoint. return; seek { // block other threads (timer events) pubisbeingcreated.reset(); // stuff } ... { // restore access other threads pubisbeingcreated.set(); } }
now both methods seem work i know 1 preferable use (more efficient?). lean towards using concurrentdictionary
allows finer filtering of threads, i.e. no 2 threads allowed work specific endpoint vs. no 2 threads allowed work specific endpoint type (pubs , subs in manualresetevents). there might solution superior mine, info appreciated.
in no case should utilize manualresetevent
purpose. it's improve utilize objects provide higher-level abstractions, if wanted command @ low level, using .net's monitor class (via lock
statement, , monitor.wait()
, monitor.pulse()
methods improve using manualresetevent
.
you seem have reasonably standard producer/consumer scenario. in case, seems me rather concurrentdictionary
, improve off concurrentqueue
. producer enqueue things, while consuming threads dequeue them processing.
c# multithreading
No comments:
Post a Comment