1

J'utilise la capacité de EF 6 à utiliser les propriétés d'Enum dans un objet entité.Entity Framework 6 Accès DBContext asynchrone avec Enums

Lorsque j'essaie d'interroger la source de données de manière asynchrone à l'aide de cette propriété enum dans le cadre des critères, la requête ne retourne jamais. Cependant, si je fais la requête de manière synchrone, elle se termine avec succès. Le SQL généré par EF est identique dans les deux cas et est correct.

Voici une version simplifiée de mon entity object:

public class RoleGroup { 
    public int Id { get; set; } 

    [Column("RequestSubTypeId")] 
    public SubTypeEnum? SubTypeId { get; set; } 
} 

Voici une version simplifiée de mon enum:

public enum SubTypeEnum { 
    AccountsPayableInquiry = 1, 
    PayrollInquiry = 2, 
    BillingInquiry = 3 
} 

Voici le method que je utilise pour récupérer un groupe de rôles de la base de données, basé sur le paramètre subTypeId:

public async Task<RoleGroup> GetRoleGroupBySubType(SubTypeEnum subTypeId) { 
    return await Context.WorkflowRoleGroups 
         .FirstAsync(roleGroup => roleGroup.SubTypeId == subTypeId); 
} 

En utilisant Context.Database.Log = s => Debug.WriteLine(s); Je suis en mesure de voir que l'instruction SQL suivante est produit par le procédé ci-dessus:

SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[RequestSubTypeId] AS [RequestSubTypeId] 
FROM [dbo].[WorkflowRoleGroups] AS [Extent1] 
WHERE [Extent1].[RequestSubTypeId] = @p__linq__0 

-- p__linq__0: '1' (Type = Int32, IsNullable = false) 

Cependant, c'est aussi loin que l'exécution obtient. Rien ne se passe, aucune erreur n'est lancée. Dans la fenêtre de sortie, je vois "Le Thread est sorti avec le code 0". Lorsque je rends la méthode synchrone, comme dans l'exemple ci-dessous, les résultats corrects sont renvoyés à partir de la base de données et tout est OK. La requête SQL générée est identique à la requête asynchrone.

public RoleGroup GetRoleGroupBySubType(SubTypeEnum subTypeId) { 
    return Context.WorkflowRoleGroups 
        .First(roleGroup => roleGroup.SubTypeId == subTypeId); 
} 

Je vous remercie de toute orientation à comprendre pourquoi l'utilisation async avec un enum dans le cadre des critères provoque ce problème.

+0

Cela n'a probablement rien à voir avec EF mais quelque chose à voir avec votre utilisation de async/await et le mélange avec quelque chose comme 'Task.Result' (* qui provoquera un blocage) * dans la pile des appels. La pile d'appels complète devrait utiliser async/await à chaque point (aussi appelé async). Sans voir tous les autres codes dans la pile d'appels, il n'y a aucun moyen de savoir quelle partie est à l'origine du blocage. – Igor

+0

Très intéressant. Vous êtes mort-sur. La méthode synchrone appelant cela avait '.Result' à la fin. J'ai effectué un test rapide en enveloppant l'appel de la méthode async dans 'Task.Run (async() => wait GetRoleGroupBySubType (subTypeId)). Result' et cela a fonctionné sans problème. Je voudrais en savoir plus sur pourquoi '.Result' provoque un blocage, mais' Task.Run(). Result' ne le fait pas. Connaissez-vous par hasard une bonne source pour plus d'informations? p.s. Faites votre commentaire une réponse et je vais accepter. – Sam

Répondre

2

Cela n'a probablement rien à voir avec EF mais quelque chose à voir avec l'utilisation de async/await et le mélange avec quelque chose comme Task.Result (qui provoquera un blocage) dans la pile des appels. La pile d'appels complète devrait utiliser async/await à chaque point (aussi appelé async). Sans voir tous les autres codes dans la pile d'appels, il n'y a aucun moyen de savoir quelle partie est à l'origine du blocage.

Voici une bonne source pour comprendre pourquoi/comment l'interblocage peut se produire Don't Block on Async Code. Stephen Cleary (auteur de l'article référencé) répond également couramment aux questions async-wait sur SO.

+1

Fantastique - merci Igor! – Sam