2017-02-18 76 views
0

比方说,我有以下方法,即某些工作完成后调用回调。我需要防止局部变量操作。在方法范围

public class MyClass 
    { 
     private static object _synblock = new object(); 

    public void MyCallBackMethod() 
    { 
     Dictionary<int, int> myDict = new Dictionary<int, int>(); 

     lock(_synblock) 
     { 
      myDict.Add(1, 1); 
     } 

    } 
} 

该方法可以被多个线程调用。在这种情况下,是否需要同步对此方法范围中定义的本地变量myDict执行的任何操作(如上所述)?还是完全没有必要?

+0

每个呼叫都将有自己的那个对象的实例所以不需要任何同步 –

回答

1

一般规律是不以保护实例级会员(和数据)在多线程环境中的并发访问。理由非常简单:多线程是一个单独的问题。

我的建议是做一个多线程的包装,只有知道如何访问同步。这又需要有一个基类或者接口来暴露你的类的特征。

public interface ISomeInterface 
{ 
    void MyCallBackMethod(); 
} 

public class MyClass : ISomeInterface 
{ 
    private int Data { get; set; } 
    public void MyCallBackMethod() 
    { 
     Dictionary<int, int> myDict = new Dictionary<int, int>(); 
     myDict.Add(1, 1); 
     // access this.Data - this is the part that would 
     // make problems in case of multithreaded access 
    } 
} 

public class ThreadSafe : ISomeInterface 
{ 
    private ISomeInterface Contained { get; } 
    private object SyncRoot { get; } = new object(); 

    public ThreadSafe(ISomeInterface contained) 
    { 
     this.Contained = contained; 
    } 

    public void MyCallBackMethod() 
    { 
     lock (this.SyncRoot) 
     { 
      this.Contained.MyCallBackMethod(); 
     } 
    } 
} 
+0

如何赋予其在方法作用域的变量是基类可能是在这种情况下有帮助吗? –

+0

我想会有其他用途。只有局部范围内的变量显然没有理由保护任何东西。 –

2

这完全没有必要。每次调用MyCallbackMethod时,都会实例化一个新的myDict对象。如果多个线程同时使用同一个实例,则只需保护对Dictionary<,>的访问

+0

我对你的答案的最后部分有点困惑。所以如果MyClass是一个单一的班级,那么我仍然需要锁定myDict? –

+0

否。如果'Dictionary <,>'是该类中的一个字段,那么如果该类的实例在多个线程中使用,则需要对其进行保护。在你的例子中,它是一个方法中的变量,它总是*是唯一的实例 – Tim

0

这完全没有必要,因为线程之间不能共享局部变量。所以从来没有confictions