2016-06-22 10 views
-1

Ich versuche, eine generische Methode zu erstellen, die einen Delegaten akzeptiert. Der einzige Zweck der Methode besteht darin, sicherzustellen, dass jeder eindeutige Codeblock, den Sie an ihn übergeben, nur von jeweils einem Thread gleichzeitig aufgerufen wird. Ich betone das Wort einzigartig, da eindeutige Codeblöcke nebeneinander laufen können, müssen doppelte Codeblöcke synchron laufen. Gibt es ein sauberes Muster, um dies zu erreichen?Wie erzwinge ich einen Mutex auf einem Delegaten

+0

Verwenden Sie Mutex, Lock oder Sophomores? Was hast du genau versucht? – Mekap

+0

Ich habe alle von ihnen ausprobiert. Ich suche wirklich nach dem richtigen Muster, hauptsächlich basierend auf den Anforderungen. – user1701153

+0

@Mekap: Sie meinten Semaphor? –

Antwort

2

Sie können etwas tun:

namespace RunSafe 
{ 
    // Declare a delegate type 
    public delegate void RunSafeDelegate(); 


    public class SafeRunner 
    { 
     private object _lock = new Object(); 

     public void Runner(RunSafeDelegate runsafe) 
     { 
      lock(this._lock) 
      { 
       runsafe(); 
      } 
     } 
    } 
} 
+0

Danke Dex. Gibt es eine Möglichkeit, die Sperre nur dann zu erzwingen, wenn der Codeblock derselbe ist? Ich brauche das im Wesentlichen zu skalieren, damit, wenn ein anderer Block des Codes hereinkommt, es als eine getrennte Sperre handeln sollte. – user1701153

+1

@ user1701153 das ist kein guter Weg, es zu tun. Code ist unveränderlich. Es muss nicht geschützt werden. Sperren schützen Daten, nicht Code. – usr

+0

@usr Letztendlich handelt der Code auf Dinge, die ich schützen muss. Zum Beispiel könnte ein Codeblock, den ich übergeben würde, einen freien tcp-Port erhalten. Ich möchte das synchronisieren, um Kollisionen zu vermeiden. Etc. – user1701153

0

Letztlich mich Dex Star Codebeispiel führen den Weg nach unten die ich suchte.

Wenn es irgendwelche Bedenken gibt, lass es mich wissen. Ich glaube, das ist eine solide Lösung. Hinweis: Ich verwende absichtlich einen benannten Mutex, da beim Zugriff auf Ressourcen möglicherweise mehrere Prozesse beteiligt sind.

// test code 
RunSafeDelegate rsd1 =() => { /* some code i need synchronous */ }; 
RunSafeDelegate rsd2 =() => { /* other code i need synchronous */ }; 

var util = new UtilityClass(); 
util.RunSafe(rsd1, "myMutexName1"); 
util.RunSafe(rsd2, "myMutexName2"); 

// implementation 
public class UtilityClass 
{ 
    public delegate void RunSafeDelegate(); 

    public void RunSafe(RunSafeDelegate runSafe, string mutexName) 
    { 
     const int WAIT_ONE_TIMEOUT = 30000; 

     var sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); 
     var mar = new MutexAccessRule(sid, MutexRights.FullControl, AccessControlType.Allow); 
     var ms = new MutexSecurity(); 

     ms.AddAccessRule(mar); 

     bool mutexCreated; 

     using(var mutex = new Mutex(false, mutexName, out mutexCreated, ms)) 
     { 
      var signalReceived = false; 

      try 
      { 
       try 
       { 
        signalReceived = mutex.WaitOne(WAIT_ONE_TIMEOUT, false); 

        if(!signalReceived) 
        { 
         throw new TimeoutException("Exclusive access timeout for mutex: " + mutexName); 
        } 
       } 
       catch(AbandonedMutexException) 
       { 
        signalReceived = true; 
       } 

       runSafe(); 
      } 
      finally 
      { 
       if(signalReceived) 
       { 
        mutex.ReleaseMutex(); 
       } 
      } 
     } 
    } 
} 
+0

Ich bin froh, dass du hast, was du brauchst. Wenn Sie Mutexes verwenden, sind sie IDisposable, also sollten Sie 'using (var mutex = neuer Mutex (false, mutexName)) {}' ... verwenden. Da Ihre Klasse keine Instanzmitglieder mehr hat, können Sie sie erstellen und seine Methoden 'static' und vermeiden es, sie instanziieren zu müssen. –

+0

@DexStar Danke Dex. Ich schätze den Rat sehr. Ich habe meine Implementierung basierend auf Ihrem Feedback und einigen tollen Informationen aktualisiert, die ich in einem anderen Beitrag gefunden habe: http://stackoverflow.com/questions/229565/what-isa-good-pattern-for-using-a-global- Mutex-in-c – user1701153

Verwandte Themen