2010-06-15 4 views
2

Tenir compte cet extrait de code:Les délégués statiques sont-ils sûrs pour les threads?

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); 

Les délégués sont dans le thread-safe ApplicationContext de classe statique dans le sens où plusieurs threads peuvent-les invoquer?

À quels problèmes potentiels serai-je confronté si je poursuis cette approche?

+0

S'il vous plaît expliquer plus ce que vous entendez par délégué statique. – leppie

+0

@leppie Dans l'exemple de code, la variable Func statique AuthenticationProvider est un délégué statique. – leypascua

Répondre

3

Les délégués sont dans le thread-safe ApplicationContext classe statique au sens que plusieurs-threads peuvent invoquer les ?

Oui. Mais un délégué est aussi sûr que la méthode vers laquelle il pointe. Donc, si les méthodes appelées par vos délégués AuthenticationProvider et UnitOfWorkFactory sont thread-safe, vos délégués le seront également.

Dans le code que vous avez fourni, il s'agit simplement d'appels de constructeur. Il n'est pas vraiment beaucoup plus sûr que les threads (à moins que vous ayez une logique de threading folle dans vos constructeurs - j'espère certainement pas).

Quels problèmes potentiels vais-je rencontrer si Je poursuis cette approche?

Aucune conséquence directe de l'appel de vos délégués. Encore une fois, les seules préoccupations concernant la sécurité des threads que vous devriez vous inquiéter sont celles qui se rapportent aux méthodes réelles appelées par vos délégués (dans ce cas, les constructeurs pour LdapAuthenticationProvider et EFUnitOfWorkFactory).

MISE À JOUR: limpalex fait une bonne observation: dans le code que vous avez posté, vous êtes en fait appeler la méthodeUninitialized<TService> dans le constructeur statique pour votre classe ApplicationContext, qui lèvera une exception. Ce que vous voulez faire est attribuer vos délégués à la méthode. Je pense que ce que vous allez pour quelque chose comme ceci:

// 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>; 
2

Votre fonction initialisés() ne renvoie pas un objet Func qui jette une exception, il jette juste une exception. Parce que cela se produira dans le constructeur statique ApplicationContext, ce type deviendra inutilisable. Vous devriez faire smth comme ça "return() => throw new IOE();"

+0

Bonne prise! Merci beaucoup! – leypascua

+0

Bonne trouvaille. Je l'ai manqué moi-même. –

Questions connexes