Signalr: HubConnection.Stop يستغرق 30 ثانية على عميل Silverlight

تم إنشاؤها على ٢٨ يونيو ٢٠١٤  ·  9تعليقات  ·  مصدر: SignalR/SignalR

أحاول إغلاق اتصال SignalR قبل أن يقوم المستخدمون بتسجيل الخروج من عميل silverlight الخاص بي باستخدام هذا الرمز ويستغرق ذلك 30 ثانية. رأيت https://github.com/SignalR/SignalR/issues/2191 وربما لم يتم تطبيق الإصلاح الخاص بعميل .net على عميل SIlverlight؟

رمز الإيقاف الذي يستغرق 30 ثانية - لا يتم استدعاء هذا من داخل طريقة On ..

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

التعليق الأكثر فائدة

yowl - إحدى الطرق للتغلب على هذه المشكلة هي استدعاء .Stop في مؤشر ترابط غير تابع لواجهة المستخدم - على سبيل المثال: await Task.Factory.StartNew(() => hubConnection.Stop()); سيكون الحل البديل الآخر هو تعيين مهلة الإيقاف على 0 مثل هذا: hubConnection.Stop(new TimeSpan(0, 0, 0, 0)); - لاحظ أنه في هذه الحالة ، لن يتم إرسال طلب الإيقاف إلى الخادم مطلقًا.

ال 9 كومينتر

شكرا ، سوف نلقي نظرة. إذا كان بإمكانك مشاركة أي معلومات أخرى قد تساعدنا في إعادة إنتاج المشكلة ، فيرجى القيام بذلك.

على الرغم من أننا نرسل طلب Abort ، إلا أنه في الواقع لم يتم إرساله أبدًا بواسطة HttpClient عند استخدام مكتبة HttpClient المحمولة. 30 ثانية هي المهلة الافتراضية التي ننتظرها للاستجابة لطلب الإلغاء. حتى أكتشف سبب عدم قيام HttpClient الأساسي بإرسال طلب الإلغاء ، يمكنك استخدام التحميل الزائد Stop(TimeSpan) وتوفير مهلة أقل.

يبدو أنه على الرغم من أن عميل SignalR يستدعي HttpClient.SendAsync() فإن الطلب في الواقع لا يتم إرساله أبدًا إلى الخادم. لقد قمت بتتبعه وصولاً إلى طريقة BeginInvokeImpl التي تستدعي NativeHost.Current.RuntimeHost.RaiseAsyncCallback (انظر تتبع المكدس أدناه) ولكن لا يتم استدعاء رد الاتصال (الذي هو في هذه الحالة InternalBeginGetResponse ). نظرًا لأنه من الممكن أن أرى أن InternalBeginGetResponse هو المسؤول عن إرسال الطلب ، فلن يتم إرسال الطلب مطلقًا ويتم حظر طريقة InvokeImpl بلا حدود في انتظار اكتمال رد الاتصال.

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#

هذا بسبب الجمود. نقوم بحظر الخيط في انتظار الاستجابة لطلب الإحباط إلى الخادم. إذا كان مؤشر الترابط الذي نحظره هو مؤشر ترابط واجهة المستخدم ، فسيؤدي ذلك إلى قفل مسدود لأن Silverlight يريد إرسال الطلب في مؤشر ترابط واجهة المستخدم.

yowl - إحدى الطرق للتغلب على هذه المشكلة هي استدعاء .Stop في مؤشر ترابط غير تابع لواجهة المستخدم - على سبيل المثال: await Task.Factory.StartNew(() => hubConnection.Stop()); سيكون الحل البديل الآخر هو تعيين مهلة الإيقاف على 0 مثل هذا: hubConnection.Stop(new TimeSpan(0, 0, 0, 0)); - لاحظ أنه في هذه الحالة ، لن يتم إرسال طلب الإيقاف إلى الخادم مطلقًا.

إصلاح # 3067 سوف "يصلح" هذه المشكلة.

"Fixed" في 7358f1d - لم نعد نحظر تلقي استجابة لطلب الإحباط.

اضطررنا إلى التراجع عن التغيير لأنه قدم مشكلتين وأجناس تمكنا من تحديدهما وربما بعضًا لم نصل إليه. أصبح من الواضح أن التغيير محفوف بالمخاطر. سنحتاج إلى إعادة التفكير في تفاعل اتصال النقل لإصلاح ذلك بشكل صحيح و / أو جعل إيقاف الاتصال غير متزامن.

سننظر في هذا الإصدار 3

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات