Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.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#_Multithreading_Static_Thread Safety - Fatal编程技术网

C# 接受变量的静态成员是否会损坏?

C# 接受变量的静态成员是否会损坏?,c#,multithreading,static,thread-safety,C#,Multithreading,Static,Thread Safety,我在形成这个问题时遇到了困难,所以我将尝试用几种方式来陈述它,这样就不会重复通常关于静态方法的讨论。这可能更像是一个架构问题 如果在接受传入变量的静态类上有一个静态成员,那么如果操作使用率高且运行时间长,是否存在数据冲突/损坏的风险?IE:接受对象图类型的数据访问类,用于持久化到数据库中 例如: namespace MyApp.DAL.People { public static class Person { public static void Insert(Entities.Peo

我在形成这个问题时遇到了困难,所以我将尝试用几种方式来陈述它,这样就不会重复通常关于静态方法的讨论。这可能更像是一个架构问题

如果在接受传入变量的静态类上有一个静态成员,那么如果操作使用率高且运行时间长,是否存在数据冲突/损坏的风险?IE:接受对象图类型的数据访问类,用于持久化到数据库中

例如:

namespace MyApp.DAL.People
{

public static class Person
{
    public static void Insert(Entities.People.Person p)
    {
        // ADO.net code, try catch etc, execute to db, call other private method
        ....
        Helper(p);
    }

    private static void Helper(Entities.People.Person p)
    {
        // do work...

    }
}

}
如果用户“A”启动了一个
Person.Insert(myNewPerson)
调用操作,那么在用户“B”使用静态类和方法将其“Person对象”保存到数据库之前,该过程是否完整完成

这些操作是串行的还是异步的,本质上是为了使用静态类而阻塞的

如果应用程序(开发人员)试图在应用程序空间中使用多个线程,这是否只是一个问题

除非为应用程序显式地启动另一个线程,否则一切都在单个线程上运行吗


作为旁注,这是我在SO上的第一篇帖子-特别感谢所有花时间发布问题/答案的家伙-感谢你们的时间

如果对可变数据结构进行多线程、不同步的写入,则始终可能发生损坏。静态成员在这方面并不特殊。如果要锁定对它们的访问,必须显式地这样做

public static class Person {
    private readonly object syncLock = new object();

    public static void Insert(Person p) {
        lock(syncLock) {
            //...
        }
    }

    // etc...
}

注意:如果您没有进行多线程访问,那么由于只使用一个线程,所有内容都将以串行方式运行。

如果两个不同的线程同时调用
Person.Insert
,它们将同时执行。除非方法中有明确的阻塞

线程
A
p
参数中传递的数据将无法通过线程
B
访问。当然,假设这两个线程向完全不同的对象实例传递引用


只要
Insert
方法中没有任何内容访问外部作用域中的任何内容,调用就完全安全。例如,两个线程的所有方法局部变量都将不同。只有当方法(或它调用的方法)开始访问外部作用域中的数据时,您才会出现问题。

@Richard:还要注意,C#本身不会启动新线程。即使是按钮单击之类的表单事件也要等到运行的方法终止后才能执行。你必须显式地启动新线程,或者通过调用一个这样做的方法(async stuff、BeginInvoke等方法)。@OlivierJacot Descombes:谢谢你,在你和Jim之间,你已经完全回答了我的问题,让我放心。我刚刚开始深入研究多线程,一点知识能让你思考和质疑那些没有被打破的东西,这真是太神奇了。谢谢大家!谢谢迈克,我很感谢你的意见。是的,此应用程序仅为单线程。我找不到任何简单地说“你的应用程序在一个线程上串行运行”的东西,除非你不这样做。(我相信这在技术上并不是绝对的,但就这个主要问题而言,这些答案真的很有帮助!谢谢。