Signalr: HubConnection.Stop tarda 30 segundos en el cliente Silverlight

Creado en 28 jun. 2014  ·  9Comentarios  ·  Fuente: SignalR/SignalR

Intento cerrar la conexión SignalR antes de que los usuarios cierren la sesión de mi cliente Silverlight usando este código y me toma 30 segundos hacerlo. Vi https://github.com/SignalR/SignalR/issues/2191 y tal vez la solución para el cliente .net no se aplica al cliente SIlverlight.

Código de detención que tarda 30 segundos: no se llama desde un método On ..

    void StopChat()
    {
        if (hubConn != null)
        {
            hubConn.Stop();
        }
    }
.NET Bug

Comentario más útil

@yowl : una forma de await Task.Factory.StartNew(() => hubConnection.Stop()); otra solución alternativa sería establecer el tiempo de espera de parada en 0 de esta manera: hubConnection.Stop(new TimeSpan(0, 0, 0, 0)); - tenga en cuenta que, en este caso, la solicitud de cancelación nunca se enviará al servidor.

Todos 9 comentarios

Gracias, echaremos un vistazo. Si puede compartir más información que pueda ayudarnos a reproducir el problema, hágalo.

Aunque enviamos una solicitud de cancelación, en realidad nunca la envía HttpClient cuando se usa la biblioteca portátil HttpClient. Los 30 segundos es el tiempo de espera predeterminado que esperamos la respuesta a la solicitud de cancelación. Hasta que descubra por qué el HttpClient subyacente nunca envía la solicitud Abort, puede usar la sobrecarga Stop(TimeSpan) y proporcionar un tiempo de espera menor.

Parece que aunque el cliente SignalR invoca HttpClient.SendAsync() la solicitud nunca se envía al servidor. Lo rastreé hasta el método BeginInvokeImpl que llama a NativeHost.Current.RuntimeHost.RaiseAsyncCallback (vea el seguimiento de la pila a continuación) pero la devolución de llamada (que en este caso es InternalBeginGetResponse ) nunca se invoca. Dado que por lo que pude ver, InternalBeginGetResponse es responsable de enviar la solicitud, la solicitud nunca se envía y el método InvokeImpl está bloqueado infinitamente esperando que se complete la devolución de llamada.

System.Windows.RuntimeHost.dll!System.Windows.RuntimeHost.ManagedRuntimeHost.RaiseAsyncCallback(System.IntPtr pDelegate, bool useFastPath) Line 191 C# System.Windows.dll!System.Windows.Threading.Dispatcher.BeginInvokeImpl(System.Windows.Threading.DispatcherPriority priority, bool useFastPath, System.Delegate d, object[] args) Line 105 + 0x30 bytes C# System.Windows.dll!System.Windows.Threading.Dispatcher.InvokeImpl(System.Windows.Threading.DispatcherPriority priority, bool useFastPath, System.Delegate d, object[] args) Line 174 + 0x3d bytes C# System.Windows.dll!System.Net.Browser.AsyncHelper.BeginOnUI(System.Net.Browser.BeginMethod beginMethod, System.AsyncCallback callback, object state) Line 142 + 0x4e bytes C# System.Windows.dll!System.Net.Browser.BrowserHttpWebRequest.BeginGetResponse(System.AsyncCallback callback, object state) Line 342 + 0x27 bytes C# System.Net.Http!System.Net.Http.HttpWebRequest.BeginGetResponse(System.AsyncCallback callback, object state) Line 138 + 0x22 bytes C# System.Net.Http!System.Net.Http.HttpClientHandler.StartGettingResponse(System.Net.Http.HttpClientHandler.RequestState state) Line 910 + 0x2b bytes C# System.Net.Http!System.Net.Http.HttpClientHandler.GetRequestStreamCallback.AnonymousMethod__8(System.Threading.Tasks.Task task) Line 883 + 0x15 bytes C# mscorlib.dll!System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke() Line 58 + 0xc bytes C# mscorlib.dll!System.Threading.Tasks.Task.Execute() Line 2437 + 0xb bytes C# mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj) Line 2792 + 0x9 bytes C# mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 417 + 0xd bytes C# mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot) Line 2763 C# mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution) Line 2695 + 0x1b bytes C# mscorlib.dll!System.Threading.Tasks.ThreadPoolTaskScheduler.TryExecuteTaskInline(System.Threading.Tasks.Task task, bool taskWasPreviouslyQueued) Line 104 + 0xb bytes C# mscorlib.dll!System.Threading.Tasks.TaskScheduler.TryRunInline(System.Threading.Tasks.Task task, bool taskWasPreviouslyQueued) Line 217 + 0x12 bytes C# mscorlib.dll!System.Threading.Tasks.TaskContinuation.InlineIfPossibleOrElseQueue(System.Threading.Tasks.Task task, bool needsProtection) Line 258 + 0xe bytes C# mscorlib.dll!System.Threading.Tasks.StandardTaskContinuation.Run(System.Threading.Tasks.Task completedTask, bool bCanInlineContinuationTask) Line 323 + 0x53 bytes C# mscorlib.dll!System.Threading.Tasks.Task.ContinueWithCore(System.Threading.Tasks.Task continuationTask, System.Threading.Tasks.TaskScheduler scheduler, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions options) Line 4585 + 0x12 bytes C# mscorlib.dll!System.Threading.Tasks.Task.ContinueWith(System.Action<System.Threading.Tasks.Task> continuationAction, System.Threading.Tasks.TaskScheduler scheduler, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, ref System.Threading.StackCrawlMark stackMark) Line 3834 C# mscorlib.dll!System.Threading.Tasks.Task.ContinueWith(System.Action<System.Threading.Tasks.Task> continuationAction, System.Threading.CancellationToken cancellationToken, System.Threading.Tasks.TaskContinuationOptions continuationOptions, System.Threading.Tasks.TaskScheduler scheduler) Line 3799 + 0x1b bytes C# System.Net.Http!System.Net.Http.HttpUtilities.ContinueWithStandard(System.Threading.Tasks.Task task, System.Action<System.Threading.Tasks.Task> continuation) Line 49 + 0x4b bytes C# System.Net.Http!System.Net.Http.HttpClientHandler.GetRequestStreamCallback(System.IAsyncResult ar) Line 866 + 0x7d bytes C# System.Windows.dll!System.Net.Browser.BrowserHttpWebRequest.InvokeGetRequestStreamCallback.AnonymousMethod__12(object state2) Line 786 + 0x11 bytes C# mscorlib.dll!System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(object state) Line 1253 + 0xb bytes C# mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 417 + 0xd bytes C# mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Line 1230 + 0x22 bytes C# mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 807 C# mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback() Line 1145 + 0x5 bytes C#

Esto se debe a un punto muerto. Bloqueamos el hilo esperando la respuesta a la solicitud de cancelación al servidor. Si el hilo que estamos bloqueando es el hilo de la interfaz de usuario, se producirá un bloqueo ya que Silverlight quiere enviar la solicitud en el hilo de la interfaz de usuario.

@yowl : una forma de await Task.Factory.StartNew(() => hubConnection.Stop()); otra solución alternativa sería establecer el tiempo de espera de parada en 0 de esta manera: hubConnection.Stop(new TimeSpan(0, 0, 0, 0)); - tenga en cuenta que, en este caso, la solicitud de cancelación nunca se enviará al servidor.

La solución # 3067 "solucionará" este problema.

"Solucionado" en 7358f1d: ya no bloqueamos para recibir una respuesta a la solicitud de cancelación.

Tuvimos que revertir el cambio ya que introdujo un par de problemas y carreras que pudimos identificar y posiblemente algunas que no hemos acertado. Se hizo evidente que el cambio es demasiado arriesgado. Necesitaremos repensar la interacción transporte-conexión para arreglar esto correctamente y / o hacer que la llamada de detención sea asincrónica.

Veremos esto para la v3.

¿Fue útil esta página
0 / 5 - 0 calificaciones