Sto riscontrando un deadlock quando utilizzo un'implementazione asincrona di un provider EF Core.
Dì che ho i seguenti modelli:
public class Player
{
public string PlayerId { get; set;}
public string Name { get; set;}
public List<Game> Games { get; set;}
}
public class Game
{
public string GameId { get; set; }
public string PlayerId { get; set; }
public Player Player { get; set;}
}
Ora voglio eseguire la seguente query:
ctx.Players
.Include(p => p.Games)
.Where(p => p.PlayerId == "123")
.Select(p => new {
PlayerId = p.PlayerId,
Games = p.Games.ToList()
}).ToListAsync();
Quando eseguo questo codice tramite Console Application / XUnit test funziona come escluso ... Ma quando lo eseguo tramite ASP.Net WebApi si mette in stallo e non finisce mai ...
Ho usato ConfigureAwait (false) fino in fondo per prevenire questo tipo di situazioni ma sembra che il codice problematico sia in basso. Penso che potrebbe essere sotto la libreria System.Interactive.Async che EFCore usa - Per essere più specifici è sotto: https://github.com/Reactive-Extensions/Rx.NET/blob/develop/Ix.NET/ Source / System.Interactive.Async / ToAsyncEnumerable.cs # L72 c'è una chiamata a " Result " che effettivamente blocca il thread di esecuzione.
Qualcuno ha riscontrato questo comportamento, forse c'è qualche soluzione?
Si noti che se non carico le entità "Giochi", allora tutto funziona anche bene ...
Modifica: Aggiunto lo StackTrace: (Vedi la chiamata a ToEnumerable )
21672 5 Worker Thread grpc 0 (cq 0) System.Interactive.Async.dll! System.Linq.AsyncEnumerable. ToEnumerable_ Normal mscorlib.dll! System.Threading.Monitor.Wait (oggetto obj, int millisecondsTimeout, bool exitContext) mscorlib.dll! System.Threading.Monitor.Wait (oggetto obj, int millisecondsTimeout) mscorlib.dll! System.Threading.ManualResetEventSlim .Wait (int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) mscorlib.dll! System.Threading.Tasks.Task.SpinThenBlockingWait (int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) mscorlib.dll! System.Threading.Tasks.Task.InternalWait (int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) mscorlib.dll! System.Threading.Tasks.Task.GetResultCore (bool waitCompletionNotification) mscorlib.dll! System.Threading.Tasks.Task.Result.get () System.Interactive.Async .dll! System.Linq.AsyncEnumerable.ToEnumerable_ (System.Collections.Generic.IAsyncEnumerable source) mscorlib.dll! System.Collections.Generic.List.List (raccolta System.Collections.Generic.IEnumerable) System.Core.dll! System .lin q.Enumerable.ToList (System.Collections.Generic.IEnumerable source) [Funzione Lightweight] Microsoft.EntityFrameworkCore.dll! Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.SelectAsyncEnumerable.SelectAsyncEnumerator.MoveNext (System.Threading.CancellationToken cancellationToken) mscorlib. dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext (object stateMachine) mscorlib.dll! System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib .dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run () mscorlib. dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 () ms corlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke ( mscorlib.dll! System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction (Azione System.Action, bool allowInlining, ref System.Threading.Tasks.Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib. dll! System.Threading.Tasks.Task.FinishStageThree () mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (risultato bool) mscorlib.dll! System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult (risultato bool) NG.Data .Spanner.EF.dll! NG.Data.Spanner.EF.Query.Internal.SpannerAsyncQueryingEnumerable.SpannerAsyncEnumerator.MoveNext (System.Threading.CancellationToken cancellationToken) Riga 55 [Ripresa del metodo Async] mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBu ilderCore.MoveNextRunner.InvokeMoveNext (object stateMachine) mscorlib.dll! System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext .Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run () mscorlib.dll! System.Runtime.CompilerServices. AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices .AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Threading.Tasks.AwaitTaskContinuation.RunOrSchedul eAction (Azione System.Action, bool allowInlining, ref System.Threading.Tasks.Task.Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib.dll! System.Threading.Tasks.Task.FinishStageThree () mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (risultato bool) mscorlib.dll! System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult (risultato bool) Microsoft.EntityFrameworkCore.dll! Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider. SelectAsyncEnumerable.SelectAsyncEnumerator.MoveNext (System.Threading.CancellationToken cancellationToken) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext (object stateMachine) mscorlib.dll! System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext , System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato dell'oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 () mscorlib.dll ! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib. dll! System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction (Azione System.Action, bool allowInlining, ref System.Threading.Tasks.Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib.dll! Sistema .Threading.Tasks.Task.FinishStageThree () mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (risultato bool) mscorlib.dll! System.Runtime.CompilerServices.AsyncTaskMethodBuilder.S etResult (risultato bool) Microsoft.EntityFrameworkCore.Relational.dll! Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable.AsyncEnumerator.MoveNext (System.Threading.CancellationToken cancellationToken) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext ( object stateMachine) mscorlib.dll! System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading .ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 ( ) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.I nvoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction (Azione System.Action, bool allowInlining, ref System.Threading.Tasks.Task.Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib.dll! System.Threading.Tasks.Task.FinishStageThree () mscorlib .dll! System.Threading.Tasks.Task.TrySetResult (risultato bool) mscorlib.dll! System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult (risultato bool) Microsoft.EntityFrameworkCore.Relational.dll! Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable .AsyncEnumerator.BufferlessMoveNext (buffer bool, System.Threading.CancellationToken cancellationToken) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext (object stateMachine) mscorlib.dll! Sys tem.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading .ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 () mscorlib.dll! System. Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! Sistema .Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction (System.Azione azione, bool allowInlining, ref System.Threading.Tasks. Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib.dll! System.Threading.Tasks.Task.FinishStageThree () mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (System .__ Canon risultato) mscorlib.dll! System.Threading.Tasks.TaskCompletionSource.TrySetResult (System .__ risultato Canon) Microsoft.EntityFrameworkCore.Relational.dll! System.Threading.Tasks.TaskExtensions.Cast.AnonymousMethod__0 (System.Threading.Tasks.Task t) mscorlib.dll! System.Threading.Tasks.ContinuationTaskFromResultTask.InnerInvoke () mscorlib.dll! System.Threading.Tasks.Task.Execute () mscorlib.dll! System.Threading.Tasks.Task.ExecutionContextCallback (oggetto obj) mscorlib.dll ! System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System. Threading.ContextCallback callback, objec t stato, bool preserveSyncCtx) mscorlib.dll! System.Threading.Tasks.Task.ExecuteWithThreadLocal (ref System.Threading.Tasks.Task currentTaskSlot) mscorlib.dll! System.Threading.Tasks.Task.ExecuteEntry (bool bPreventDoubleExecution) mscorlib.dll ! System.Threading.Tasks.ThreadPoolTaskScheduler.TryExecuteTaskInline (attività System.Threading.Tasks.Task, bool taskWasPreviouslyQueued) mscorlib.dll! System.Threading.Tasks.TaskScheduler.TryRunInline (attività System.Threading.Tasks.Task, bool taskWasPreviouslyQueued) mscorlib .dll! System.Threading.Tasks.TaskContinuation.InlineIfPossibleOrElseQueue (task System.Threading.Tasks.Task, bool needsProtection) mscorlib.dll! System.Threading.Tasks.StandardTaskContinuation.Run (System.Threading.Tasks.Task completedTask, bool bCanInlineContinuationTask mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib.dll! System.Threading.Tasks.Task.FinishStageThree () mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (Sistema .__ risultato Canon) mscorlib.dll! System.Ru ntime.CompilerServices.AsyncTaskMethodBuilder.SetResult (risultato dell'oggetto) NG.Data.Spanner.EF.dll! NG.Data.Spanner.EF.Storage.Internal.SpannerRelationalCommand.ExecuteAsync (connessione Microsoft.EntityFrameworkCore.Storage.IRelationalConnection, stringa executeMethod, System .Collections.Generic.IReadOnlyDictionary parameterValues, bool closeConnection, System.Threading.CancellationToken cancellationToken) Line 41 [Ripresa del metodo Async] mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext (object stateMachine) mscorlib.dll! System. Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNex tRunner.Run () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter .OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction (Azione System.Action, bool allowInlining, ref System.Threading. Tasks.Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib.dll! System.Threading.Tasks.Task.FinishStageThree () mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (System .__ risultato Canon) mscorlib.dll! System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult (risultato dell'oggetto) NG.Data.Spanner.EF.dll! NG.Data.Spanner.EF.Storage.Internal.SpannerRelationalCommand.ExecuteAsync (NG.Data .Spanner.EF.Stor age.Internal.IOBehavior ioBehavior, Microsoft.EntityFrameworkCore.Storage.IRelationalConnection connection, stringa executeMethod, System.Collections.Generic.IReadOnlyDictionary parameterValues, bool closeConnection, System.Threading.CancellationToken cancellationToken) Riga 128 [Resuming Async Method] mscorlib.dll! System .Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext (object stateMachine) mscorlib.dll! System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run () mscorlib.dll! System .Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 () m scorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke ( mscorlib.dll! System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction (Azione System.Action, bool allowInlining, ref System.Threading.Tasks.Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib. dll! System.Threading.Tasks.Task.FinishStageThree () mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (System .__ risultato Canon) mscorlib.dll! System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult (System.Data. Risultato Common.DbDataReader) NG.Data.Spanner.dll! NG.Data.Spanner.SpannerCommand.ExecuteDbDataReaderAsync (comportamento System.Data.CommandBehavior, System.Threading.CancellationToken cancellationToken) Riga 67 [Ripristino del metodo Async] mscorlib.dll! System. Runtim e.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext (object stateMachine) mscorlib.dll! System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! Sistema .Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run () mscorlib.dll! System. Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! Sistema .Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Threading.Tasks.Aw aitTaskContinuation.RunOrScheduleAction (Azione System.Action, bool allowInlining, ref System.Threading.Tasks.Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib.dll! System.Threading.Tasks.Task.FinishStageThree () mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (System .__ risultato Canon) mscorlib.dll! System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult (Google.Cloud.Spanner.V1.ResultSet result) NG.Data. Spanner.dll! NG.Data.Spanner.SpannerConnection.RunQuery (stringa commandText) Riga 118 [Ripresa del metodo Async] mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext (object stateMachine) mscorlib.dll! System.Threading .ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextC callback allback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime .CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System. Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction (Azione System.Action, bool allowInlining, ref System.Threading.Tasks.Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib.dll! System.Threading.Tasks .Task.FinishStageThree () mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (System .__ risultato Canon) mscorlib.dll! System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult (Google .Cloud.Spanner.V1.ResultSet result) Google.Api.Gax.Grpc.dll! Google.Api.Gax.Grpc.ApiCallRetryExtensions.WithRetry.AnonymousMethod__0 (Google.Cloud.Spanner.V1.ExecuteSqlRichiesta richiesta, Google.Api.Gax .Grpc.CallSettings callSettings) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.InvokeMoveNext (object stateMachine) mscorlib.dll! System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback , stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore .MoveNextRunner.Run () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.Contin uationWrapper.Invoke () mscorlib.dll! System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__0 () mscorlib.dll! System.Runtime.CompilerServices.AsyncMethodBuilderCore.ContinuationWrapper.Invoke () mscorlib.dll! System.Threading.Tasks.AwaitTaskContinuation .RunOrScheduleAction (Azione System.Action, bool allowInlining, ref System.Threading.Tasks.Task currentTask) mscorlib.dll! System.Threading.Tasks.Task.FinishContinuations () mscorlib.dll! System.Threading.Tasks.Task.FinishStageThree ( mscorlib.dll! System.Threading.Tasks.Task.TrySetResult (System .__ risultato Canon) mscorlib.dll! System.Threading.Tasks.TaskCompletionSource.TrySetResult (Sistema .__ risultato Canon) mscorlib.dll! System.Threading.Tasks.TaskCompletionSource .SetResult (System .__ risultato Canon) Grpc.Core.dll! Grpc.Core.Internal.AsyncCall.HandleUnaryResponse (successo bool, Grpc.Core.Internal.ClientSideStatus receivedStatus, byte [] receivedMessage, Grpc.Core.Metadata responseHeaders) Grpc. Core.dll! Grpc.Core.Internal.CallSafeHand le.StartUnary.AnonymousMethod__0 (successo bool, contesto Grpc.Core.Internal.BatchContextSafeHandle) Grpc.Core.dll! Grpc.Core.Internal.CompletionRegistry.HandleBatchCompletion (successo bool, Grpc.Core.Internal.BatchContextSafeHandle ctx, Grpc.Core. Internal.BatchCompletionDelegate callback) Grpc.Core.dll! Grpc.Core.Internal.CompletionRegistry.RegisterBatchCompletion.AnonymousMethod__0 (successo bool) Grpc.Core.dll! Grpc.Core.Internal.GrpcThreadPool.RunHandlerLoop (Grpc.Core.Internal.CompletionQueueSafeHandle cq Grpc.Core.Profiling.IProfiler optionalProfiler) Grpc.Core.dll! Grpc.Core.Internal.GrpcThreadPool.CreateAndStartThread.AnonymousMethod__0 () mscorlib.dll! System.Threading.ThreadHelper.ThreadStart_Context (stato dell'oggetto) mscorlib.dll! System. Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext exe cutionContext, System.Threading.ContextCallback callback, stato oggetto, bool preserveSyncCtx) mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, stato oggetto) mscorlib.dll! System. Threading.ThreadHelper.ThreadStart ()
Quindi dopo un lungo debugging ho trovato il problema e ho fatto un po 'di lavoro per risolverlo. Proverò a spiegare:
Sto creando un provider di EF Core su Google Spanner db . Per questo utilizzo l' API DotNet di Google Spanner , sebbene non sia ancora un'API pubblica e molto spoglio (in realtà è solo un codice generato automaticamente).
Questa API utilizza l'API gRPC e ciò che ho visto è che durante la prima chiamata asincrona con questa API, il thread gRPC (Il gRPC ha la sua implementazione del thread thread) viene utilizzato e verrà utilizzato per le successive chiamate di esecuzione, poiché le continuazioni eseguire solo su questo thread dal pool di thread gRPC.
EFCore chiama il ToEnumerable per l'elenco "Giochi" che utilizza la libreria System.Interactive.Async. Nell'implementazione di ToEnumerable, in realtà chiama " Result " che blocca il thread di esecuzione e attende il risultato. Poiché il thread gRPC è utilizzato e attendi che l'esecuzione sia finita, abbiamo un deadlock ...
La mia soluzione alternativa era usare il seguente codice:
GrpcEnvironment.SetCompletionQueueCount(1);
In questo modo è possibile eseguire le continuazioni su altri thread dal pool di thread gRPC.
Questa è solo una soluzione alternativa e dovrebbe essere utilizzata. Comunque aiuta a risolvere il problema nel frattempo ...
La vera soluzione dovrebbe probabilmente essere nell'utilizzo EFCore della libreria System.Interactive.Async, in riguardo al ToEnumerable ... (dovrebbe essere puro asincrono).
Modifica: se potrebbe essere rilevante per chiunque: ha appena rilasciato un provider EF Core per Google Spanner db: https://github.com/NoGame/NG.Data.Spanner
Il tuo problema è che stai tentando di materializzare i Games
sincrono e l'oggetto proiettato in modo asincrono. Nota quanto segue:
.Select(p => new {
PlayerId = p.PlayerId,
Games = p.Games.ToList() // sync over async is blocking
}).ToListAsync();
Quello che ti aspetteresti di lavorare (in EF regolare, per esempio) è:
.Select(p => new {
PlayerId = p.PlayerId,
Games = p.Games // let the provider handle the enumeration materialization
}).ToListAsync();
Ma secondo i tuoi commenti, in realtà non restituisce i giochi sull'oggetto proiettato anonimo. Il problema, a quanto pare, è che EF Core sembra non lasciarti sfuggire l'ingenuo incarico (dovresti aggiornare la domanda per indicarlo). Mi chiedo se questo non è correlato a come. .Include()
funziona in EF Core. Non ho familiarità con la versione core di EF per offrire molto aiuto oltre a dirvi la "causa", ma in sostanza il problema è che state aspettando di ottenere un enumeratore da un'origine che attende di materializzarsi in base a tale enumerazione.