2012-02-14 39 views
13

Đôi khi chúng tôi gặp phải tình huống mà ứng dụng bị bế tắc và có vẻ như bộ điều phối bị bế tắc với một chủ đề nền đang cố gắng gọi trên bộ điều phối. Tôi không thấy rằng một trong hai luồng có bất kỳ tài nguyên được chia sẻ nào bị khóa. Chủ đề nền đã gặp phải một ngoại lệ và nó kết thúc tại miền ứng dụng đã giải quyết ủy nhiệm ngoại lệ vì không ai chọn ngoại lệ này. Điều này gọi trình xử lý ngoại lệ của chúng ta được giao nhiệm vụ bảo đảm rằng hộp thoại ngoại lệ của chúng ta được đặt vào bộ điều phối.Ứng dụng WPF bị bế tắc khi gọi trên Dispatcher

Ai đó có thể đề xuất các cách mà tôi có thể tìm ra nguyên nhân gây ra bế tắc?

Các ngăn xếp điều phối sau và trông không khác thường:

*0. System.Windows.Threading.DispatcherSynchronizationContext.Wait (source line information unavailable) 

1. System.Threading.SynchronizationContext.InvokeWaitMethodHelper (source line information unavailable) 
2. Xceed.Wpf.DataGrid.DeferredOperationManager.Process (source line information unavailable) 
3. Xceed.Wpf.DataGrid.DeferredOperationManager.Dispatched_Process (source line information unavailable) 
4. System.Windows.Threading.ExceptionWrapper.InternalRealCall (source line information unavailable) 
5. System.Windows.Threading.ExceptionWrapper.TryCatchWhen (source line information unavailable) 
6. System.Windows.Threading.Dispatcher.WrappedInvoke (source line information unavailable) 
7. System.Windows.Threading.DispatcherOperation.InvokeImpl (source line information unavailable) 
8. System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext (source line information unavailable) 
9. System.Threading.ExecutionContext.runTryCode (source line information unavailable) 
10. System.Threading.ExecutionContext.RunInternal (source line information unavailable) 
11. System.Threading.ExecutionContext.Run (source line information unavailable) 
12. System.Windows.Threading.DispatcherOperation.Invoke (source line information unavailable) 
13. System.Windows.Threading.Dispatcher.ProcessQueue (source line information unavailable 
14. System.Windows.Threading.Dispatcher.WndProcHook (source line information unavailable) 
15. MS.Win32.HwndWrapper.WndProc (source line information unavailable) 
16. MS.Win32.HwndSubclass.DispatcherCallbackOperation (source line information unavailable) 
17. System.Windows.Threading.ExceptionWrapper.InternalRealCall (source line information unavailable) 
18. System.Windows.Threading.ExceptionWrapper.TryCatchWhen (source line information unavailable) 
19. System.Windows.Threading.Dispatcher.WrappedInvoke (source line information unavailable) 
20. System.Windows.Threading.Dispatcher.InvokeImpl (source line information unavailable) 
21. System.Windows.Threading.Dispatcher.Invoke (source line information unavailable) 
22. MS.Win32.HwndSubclass.SubclassWndProc (source line information unavailable) 
    [Internal Frame, 'M-->U'] 
23. System.Windows.Threading.Dispatcher.PushFrameImpl (source line information unavailable) 
24. System.Windows.Threading.Dispatcher.PushFrame (source line information unavailable) 
25. System.Windows.Threading.Dispatcher.Run (source line information unavailable) 
26. System.Windows.Application.RunDispatcher (source line information unavailable) 
27. System.Windows.Application.RunInternal (source line information unavailable) 
28. System.Windows.Application.Run (source line information unavailable) 
29. System.Windows.Application.Run (source line information unavailable) 
30. Wmc.Gtseq.Client.Desktop.App.Main (source line information unavailable) 

Các chủ đề thứ hai ngăn xếp bắt đầu bascically từ các miền ứng dụng unhandled exception handler:

*0. System.Threading.WaitHandle.WaitOne (source line information unavailable) 

1. System.Threading.WaitHandle.WaitOne (source line information unavailable) 
2. System.Windows.Threading.DispatcherOperation+DispatcherOperationEvent.WaitOne (source line information unavailable) 
3. System.Windows.Threading.DispatcherOperation.Wait (source line information unavailable) 
4. System.Windows.Threading.Dispatcher.InvokeImpl (source line information unavailable) 
5. System.Windows.Threading.Dispatcher.Invoke (source line information unavailable) 
6. Wmc.Gtseq.Core.ForwardPort.Extensions.DispatcherExtension.InvokeIfRequired (source line information unavailable) 
7. Wmc.Gtseq.Core.ForwardPort.Utilities.DispatcherHelper.InvokeOnMainThread (source line information unavailable) 
8. Wmc.Gtseq.Core.ForwardPort.Handlers.ExceptionHandler.ThreadSafeDialogHandler (source line information unavailable) 
9. Wmc.Gtseq.Core.ForwardPort.Handlers.ExceptionHandler.ShowErrorDialog (source line information unavailable) 
10. Wmc.Gtseq.Core.ForwardPort.Handlers.ExceptionHandler.HandleException (source line information unavailable) 
11. Wmc.Gtseq.Client.Desktop.App.AppDomainUnhandledException (source line information unavailable) 

Dường như Gọi là chờ đợi như mong đợi nhưng cũng xuất hiện rằng các chủ đề chính dispatcher bị chặn. Chúng tôi đã chờ đợi nhiều phút trong những tình huống này và ứng dụng không bao giờ quay lại. Bất kỳ trợ giúp hoặc thông tin chi tiết nào sẽ được đánh giá cao. Tôi biết tôi có thể chuyển sang BeginInvoke nhưng dựa trên bối cảnh ở đây tôi lo lắng rằng chuỗi nền của tôi sẽ tiếp tục và giao diện người dùng sẽ bị chặn vì cùng một lý do hoặc hộp thoại ngoại lệ sẽ không xuất hiện.

sợi nền của chúng tôi thực hiện các dòng mã sau khi ngoại lệ xuất hiện tại miền xử lý ngoại lệ unhandled:

protected override void AppDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     ExceptionHandler.HandleException(e.ExceptionObject as Exception, false); 
    } 

public static void HandleException(Exception ex, bool closeApp) 
    { 
     ThreadSafeDialogHandler((Action)delegate { ErrorDialog.ShowDialog(ex, closeApp); });   
    } 

private static void ThreadSafeDialogHandler(Action methodCall) 
    { 
     DispatcherHelper.InvokeOnMainThread(() => { methodCall(); }); 
    } 

public static void InvokeOnMainThread(Action method) 
    { 
     Application.Current.InvokeIfRequired(method, DispatcherPriority.Normal); 
    } 

public static void InvokeIfRequired(this DispatcherObject control, Action methodcall, DispatcherPriority priorityForCall) 
    { 
     // see if we need to Invoke call to Dispatcher thread 
     if (control.Dispatcher.CheckAccess()) 
     { 
      methodcall(); 
     } 
     else 
     { 
      control.Dispatcher.Invoke(priorityForCall, methodcall); 
     } 
    } 
+0

Bạn có thể đăng mã của mình không? – Rachel

+0

Tôi đã đăng mã thực thi bắt đầu từ trình xử lý ngoại lệ chưa xử lý của miền ứng dụng. – Ben

+0

Sẽ thú vị hơn khi thấy dấu vết ngăn xếp của chuỗi giao diện người dùng trong khi bế tắc đang hoạt động. Chuỗi giao diện người dùng có thể đang chờ thứ gì đó để người điều phối bị chặn. Phá vỡ trình gỡ rối lần sau khi bế tắc xảy ra và kiểm tra dấu vết ngăn xếp của chuỗi giao diện người dùng. Nó có thể được rằng thread UI của bạn là trong một Thread.Join (hoặc một cái gì đó tương tự) trong khi chủ đề nền của bạn cố gắng để Gọi trên dispatcher? Tôi đã ngừng sử dụng Invoke một thời gian dài trước đây vì deadlocks .. chỉ BeginInvoke. – stmax

Trả lời

1

Thay vì control.Dispatcher.Invoke thử control.Dispatcher.BeginInvoke, mà đã giúp tôi trước đây trong trường hợp góc như vậy.

Ngoài ra, mã của bạn có vẻ hơi lạ với tôi. Trong ứng dụng của tôi, tôi đặt trình xử lý sự kiện AppDomain.CurrentDomain.UnhandledException trong cửa sổ chính Loaded() sự kiện. Sự kiện này được gắn vào một phương thức cục bộ của cửa sổ chính. Vì vậy, tôi không cần phải thực hiện bất kỳ Dispatcher nào, bởi vì sự kiện này đã được nâng lên trên luồng điều phối chính, ngay cả khi lỗi xảy ra trên một luồng khác hoàn toàn.

+0

Không phải lúc nào cũng có thể chuyển từ 'Gọi 'sang' BeginInvoke'. Cái cũ là đồng bộ, và cái thứ hai là không đồng bộ. Nếu callee phụ thuộc vào hiệu ứng của cuộc gọi được gọi, nó có thể dễ dàng. –

Các vấn đề liên quan