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