如何使静态方法线程安全?

use*_*100 6 c# multithreading static-methods

我编写了一个静态类,它是我从不同类调用的一些函数的存储库.

public static class CommonStructures
{
    public struct SendMailParameters
    {
        public string To { get; set; }
        public string From { get; set; }
        public string Subject { get; set; }
        public string Body { get; set; }
        public string Attachment { get; set; }
    }
}

public static class CommonFunctions
{
    private static readonly object LockObj = new object();
    public static bool SendMail(SendMailParameters sendMailParam)
    {
        lock (LockObj)
        {
            try
            {
                //send mail
                return true;
            }
            catch (Exception ex)
            {
                //some exception handling
                return false;
            }
        }
    }

    private static readonly object LockObjCommonFunction2 = new object();
    public static int CommonFunction2(int i)
    {
        lock (LockObjCommonFunction2)
        {
            int returnValue = 0;
            try
            {
                //send operation
                return returnValue;
            }
            catch (Exception ex)
            {
                //some exception handling
                return returnValue;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题1:对于我的第二个方法CommonFunction2,在这个例子中我是否使用新的静态锁,即LockObjCommonFunction2,或者我可以重用在函数开头定义的相同锁定对象LockObj.

问题2:是否存在可能导致线程相关问题的任何问题,或者我可以将代码改进为安全线程.

问题3:在传递公共类而不是结构中是否存在任何问题..在这个示例中,SendMailParameters(我使用包装所有参数,而不是将多个参数传递给SendMail函数)?

此致,MH

aia*_*tag 5

问题1:对于我的第二个方法CommonFunction2,在这个例子中我是否使用新的静态锁,即LockObjCommonFunction2,或者我可以重用在函数开头定义的相同锁定对象LockObj.

如果要同步这两种方法,则需要对它们使用相同的锁.例如,如果thread1正在访问您的Method1,并且thread2正在访问您的Method2并且您希望它们不能同时访问这两个内部,请使用相同的锁.但是,如果你只是想限制只是并发访问无论是方法1或2,使用不同的锁.

问题2:是否存在可能导致线程相关问题的任何问题,或者我可以将代码改进为安全线程.

永远记住共享资源(例如静态变量,文件)不是线程安全的,因为它们很容易被所有线程访问,因此您需要应用任何类型的同步(通过锁,信号,互斥等).

问题3:在传递公共类而不是结构中是否存在任何问题..在这个示例中,SendMailParameters(我使用包装所有参数,而不是将多个参数传递给SendMail函数)?

只要您应用适当的同步,它就是线程安全的.对于结构,请将作为参考.

底线是您需要为共享内存中的任何内容应用正确的同步.此外,您应始终注意要生成的线程的范围以及每个方法使用的变量的状态.他们是改变状态还是只依赖变量的内部状态?线程是否总是创建一个对象,尽管它是静态的/共享的?如果是,那么它应该是线程安全的.否则,如果它只是重​​用某个共享资源,那么您应该应用适当的同步.最重要的是,即使没有共享资源,死锁仍然可能发生,所以请记住C#中的基本规则以避免死锁.PS感谢Euphoric分享Eric Lippert的文章.

但要小心你的同步.尽可能将其范围限制为仅修改共享资源的位置.因为它可能会给您的应用带来不便的瓶颈,因为性能会受到很大影响.

    static readonly object _lock = new object();
    static SomeClass sc = new SomeClass();
    static void workerMethod()
    {
        //assuming this method is called by multiple threads

        longProcessingMethod();

        modifySharedResource(sc);
    }

    static void modifySharedResource(SomeClass sc)
    {
        //do something
        lock (_lock)
        {
            //where sc is modified
        }
    }

    static void longProcessingMethod()
    {
        //a long process
    }
Run Code Online (Sandbox Code Playgroud)