Tuesday 15 September 2015

multithreading - C# ConcurrentDictionary vs. ManualResetEvent for Thread Control -



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