Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 类级锁定_C#_.net_Multithreading - Fatal编程技术网

C# 类级锁定

C# 类级锁定,c#,.net,multithreading,C#,.net,Multithreading,我有一个带有一些静态方法的类。这些静态方法使用相同的资源(数据列表)。我希望此数据列表是线程安全的。因为同一个类中有许多静态方法使用相同的数据列表。我不能简单地在多线程环境中使用lock/Monitor来保护代码。如何确保只有一个线程正在执行我的类的任何方法,而其他线程应该等待该线程退出,无论它们想在我的类中运行相同的方法还是不同的方法。我怎样才能做到这一点? 下面是一些需要澄清的代码。我的工作是编写MyLibraryClass class Program { static void M

我有一个带有一些静态方法的类。这些静态方法使用相同的资源(数据列表)。我希望此数据列表是线程安全的。因为同一个类中有许多静态方法使用相同的数据列表。我不能简单地在多线程环境中使用lock/Monitor来保护代码。如何确保只有一个线程正在执行我的类的任何方法,而其他线程应该等待该线程退出,无论它们想在我的类中运行相同的方法还是不同的方法。我怎样才能做到这一点? 下面是一些需要澄清的代码。我的工作是编写
MyLibraryClass

class Program
{
    static void Main(string[] args)
    {
      
        var t1 =System.Threading.Tasks.Task.Factory.StartNew(MyLibraryClass.A);

        var t2 = System.Threading.Tasks.Task.Factory.StartNew(MyLibraryClass.B);

        t1.Wait();
        t2.Wait();
        Console.WriteLine("Completed. Press any key to continue");
        Console.ReadKey();
    }

}

class MyLibraryClass
{

    static List<int> items = new List<int>();
    static MyLibraryClass()
    {
        items.Add(5);
        items.Add(4);
    }
    public static void A()
    {
        foreach (var a in items)
        {
            Console.WriteLine(a);
            System.Threading.Thread.Sleep(300);
        }
    }

    public static void B()
    {
        System.Threading.Thread.Sleep(200);
        Console.WriteLine("Adding Number");
        items.Add(9);
    }
}
类程序
{
静态void Main(字符串[]参数)
{
var t1=System.Threading.Tasks.Task.Factory.StartNew(MyLibraryClass.A);
var t2=System.Threading.Tasks.Task.Factory.StartNew(MyLibraryClass.B);
t1.等待();
t2.等待();
Console.WriteLine(“已完成。按任意键继续”);
Console.ReadKey();
}
}
类MyLibraryClass
{
静态列表项=新列表();
静态MyLibraryClass()
{
增加第(5)项;
增加第(4)项;
}
公共静态无效A()
{
foreach(项目中的var a)
{
控制台写入线(a);
系统.线程.线程.睡眠(300);
}
}
公共静态void B()
{
系统线程线程睡眠(200);
控制台写入线(“添加编号”);
增加(9)项;
}
}
我不能简单地在多线程环境中使用lock/Monitor来保护代码

是的,你可以。这就是你的本意

如何确保只有一个线程正在执行我的类的任何方法,而其他线程应该等待该线程退出,无论它们想在我的类中运行相同的方法还是不同的方法。我怎样才能做到这一点

使用
/
监视器
。或者其他一些线程隐喻,例如线程安全集合,但
lock
是最简单的。在处理实际上是多个操作的原子单元时,线程安全集合需要更多的思考(例如,如果缺少,则测试然后添加)


另一个技巧是:不要使用可变数据的静态列表:这很少是一个好主意。

您可以为MyLibrary类使用[synchronization]属性。这将确保整个类是线程安全的。

如何确保只有一个线程在执行我的类的任何方法…
-通过不使用多线程在所有这些方法中放置一个锁块,这些方法在一个相同的
私有静态只读对象上运行_lock=new object()在所有情况下…?:)虽然对这样的类使用多线程是毫无意义的,因为您将强制顺序执行。@DGibbs是一个相当轻率的语句,先生。OP可能正在编写代码供其他工程师使用。代码甚至可能是产品。如果并发可能导致问题,它肯定会希望确保调用序列化。@PatrykĆwiek共享资源是唯一正在进行的事情,这是非常罕见的,因此它不是“无意义的”@MarcGravel足够正确,而是静态的,多线程环境中的可变数据会让我的皮肤爬行。lock/monitor确保代码块一次只由一个线程执行。但我的问题不是保护一个代码块。我有两个方法A和B。如果线程T1想要执行方法A,线程T2想要执行方法B,那么T1和T2不应该并行运行这些方法。T2只能在T1已运行完方法A时运行方法B。@ZafarYousafi方法A和B应在同一成员上建立锁。@ZafarYousafi-这不是逻辑要求。线程安全总是保护数据(状态),而不是关于方法。@ ZafarYousafi。如果您对访问共享状态的方法没有控制权,那么您是“SOL”,需要考虑从一开始就考虑线程安全的某种重构。在线程安全的集合中,您可能会有一些运气,但这些并不是一个灵丹妙药(经典的例子是“checkif-in-list,然后add”)。另一种选择是:停止使用可变共享状态。@ZafarYousafi,同样,没有任何变化;您有相同的选项:1:在方法内部使用
lock
,用于与状态对话的特定位,您说这不是选项;2:在调用方法的任何方法中使用
lock
,并接受整个方法将彼此同步,或3:使用线程安全的集合,但要理解任何根据集合状态(而不是简单地添加等)做出决策的代码都有固有的缺陷,容易受到线程竞争的影响,或者4:正确地重构代码,使代码不会直接与共享状态对话。这仅适用于.NET Framework和Xamarin应用程序。对于一般用途,有以下选项。