【问题标题】:Can Static Members that Accept Variables Become Corrupt?接受变量的静态成员会损坏吗?
【发布时间】:2013-03-26 19:29:33
【问题描述】:

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

如果您在接受传入变量的静态类上有一个静态成员,如果操作使用率高且运行时间长,是否存在数据冲突/损坏的风险? 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”开始使用静态类和方法将他的“个人对象”保存到数据库之前完全完成。

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

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

除非您为应用程序显式启动另一个线程,否则所有内容都运行在单个线程上吗?

作为旁注,这是我在 SO 上的第一篇文章 - 特别感谢所有花时间发布问题/答案的人 - 感谢您抽出宝贵的时间!

【问题讨论】:

    标签: c# multithreading static thread-safety


    【解决方案1】:

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

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

    只要Insert 方法中的任何内容都不能访问外部范围内的任何内容,这些调用都是完全安全的。例如,所有方法局部变量对于两个线程都是不同的。只有当方法(或它调用的方法)开始访问外部范围内的数据时才会出现问题。

    【讨论】:

    • @Richard:还要注意 C# 本身不会启动新线程。甚至像按钮点击这样的表单事件也要等到正在运行的方法终止,然后再执行。您必须显式启动新线程或通过调用执行此操作的方法(异步内容、BeginInvoke 等方法)。
    • @OlivierJacot-Descombes:谢谢你,在你和 Jim 之间,你完全回答了我的问题,让我放心。我刚刚开始更深入地研究多线程,令人惊讶的是,一点点知识就可以开始让你思考和质疑,嗯,那些没有被破坏的东西。谢谢大家!
    【解决方案2】:

    如果您对可变数据结构进行多线程、非同步写入,则始终存在损坏的可能性。静态成员在这方面并不特殊。如果你想锁定对它们的访问,你必须明确地这样做。

    public static class Person {
        private readonly object syncLock = new object();
    
        public static void Insert(Person p) {
            lock(syncLock) {
                //...
            }
        }
    
        // etc...
    }
    

    注意:如果您不进行多线程访问,那么由于只使用一个线程,一切都会以串行方式运行。

    【讨论】:

    • 感谢 Mike,感谢您的意见。是的,这个应用程序只有单线程。除非您不这样做,否则我找不到任何简单地说“您的应用程序在一个线程上串行运行”的内容。 (我确信这在技术上并非在所有情况下都是绝对的,但就这个拱形问题而言,这些答案真的很有帮助!谢谢。
    猜你喜欢
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多