静态委托是否是线程安全的?

时间:2010-06-15 07:27:11

标签: c# .net dependency-injection delegates

请考虑以下代码段:

public static class ApplicationContext
{
    private static Func<TService> Uninitialized<TService>()
    {
        throw new InvalidOperationException();
    }

    public static Func<IAuthenticationProvider> AuthenticationProvider = Uninitialized<IAuthenticationProvider>();
    public static Func<IUnitOfWorkFactory> UnitOfWorkFactory = Uninitialized<IUnitOfWorkFactory>();
}

//can also be in global.asax if used in a web app.
public static void Main(string[] args) 
{
    ApplicationContext.AuthenticationProvider = () => new LdapAuthenticationProvider();
    ApplicationContext.UnitOfWorkFactory = () => new EFUnitOfWorkFactory();
}

//somewhere in the code.. say an ASP.NET MVC controller
ApplicationContext.AuthenticationProvider().SignIn(username, true);

在多线程可以调用它们的意义上,静态类ApplicationContext中的委托是否是线程安全的?

如果我采用这种方法,我将面临哪些潜在问题?

2 个答案:

答案 0 :(得分:3)

  

是静态类中的委托   ApplicationContext中的线程安全   感觉多线程可以调用   它们?

是。但是委托只是与它指向的方法一样是线程安全的。

因此,如果您的AuthenticationProviderUnitOfWorkFactory代理调用的方法是线程安全的,那么您的代表也是如此。

在您提供的代码中,这些只是构造函数调用。它实际上并没有比那更安全的线程(除非你的构造函数中有一些疯狂的线程逻辑 - 我当然希望不会这样)。

  

如果,我将面临哪些潜在的问题   我采用这种方法吗?

无直接来自调用您的代理人的结果。同样,关于线程安全的唯一问题是你应该担心的是那些与你的代表调用的实际方法有关的问题(在这种情况下,是LdapAuthenticationProviderEFUnitOfWorkFactory的构造函数)。 p>

更新:limpalex做了一个很好的观察:在您发布的代码中,您实际上是在静态构造函数中调用 Uninitialized<TService>方法ApplicationContext类,它会抛出异常。您要做的是您的代理人分配给该方法。我认为你想要的是这样的:

// note: changed return type to TService to match Func<TService> signature
private static TService Uninitialized<TService>()
{
    throw new InvalidOperationException();
}

// note: removed () symbols to perform assignment instead of method call
public static Func<IAuthenticationProvider> AuthenticationProvider = Uninitialized<IAuthenticationProvider>;
public static Func<IUnitOfWorkFactory> UnitOfWorkFactory = Uninitialized<IUnitOfWorkFactory>;

答案 1 :(得分:2)

您的Uninitialized()函数不会返回抛出异常的Func对象,它只会抛出异常。 因为这会在ApplicationContext静态构造函数中发生,这种类型将变得无法使用。 你应该做那样的“return()=&gt;抛出新的IOE();”