Tôi đã cố gắng theo dõi vấn đề sau trong ứng dụng Winforms:
Số SynchronizationContext.Current
không được tiếp tục công việc (tức là .ContinueWith
) đang chạy trên chủ đề chính (Tôi mong đợi bối cảnh đồng bộ hóa hiện tại là System.Windows.Forms.WindowsFormsSynchronizationContext
).SynchronizationContext.Current is null trong Tiếp tục trên chủ đề giao diện người dùng chính
Dưới đây là đoạn code Winforms chứng minh vấn đề:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TaskScheduler ts = TaskScheduler.FromCurrentSynchronizationContext(); // Get the UI task scheduler
// This line is required to see the issue (Removing this causes the problem to go away), since it changes the codeflow in
// \SymbolCache\src\source\.NET\4\DEVDIV_TFS\Dev10\Releases\RTMRel\ndp\clr\src\BCL\System\Threading\ExecutionContext.cs\1305376\ExecutionContext.cs
// at line 435
System.Diagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");
var task = Task.Factory.StartNew(() => { });
var cont = task.ContinueWith(MyContinueWith, CancellationToken.None, TaskContinuationOptions.None, ts);
System.Diagnostics.Trace.CorrelationManager.StopLogicalOperation();
}
void MyContinueWith(Task t)
{
if (SynchronizationContext.Current == null) // The current SynchronizationContext shouldn't be null here, but it is.
MessageBox.Show("SynchronizationContext.Current is null");
}
}
}
Đây là một vấn đề đối với tôi kể từ khi tôi cố gắng sử dụng BackgroundWorker
từ việc tiếp tục, và BackgroundWorker sẽ sử dụng SynchronizationContext hiện cho các sự kiện của nó RunWorkerCompleted
và ProgressChanged
. Kể từ khi SynchronizationContext hiện tại là null khi tôi khởi động BackgroundWorker, các sự kiện không chạy trên thread ui chính như tôi dự định.
Câu hỏi của tôi:
Đây có phải là lỗi trong mã của Microsoft hay tôi đã phạm sai lầm ở đâu đó?
Thông tin thêm:
- Tôi đang sử dụng Net 4.0 (tôi chưa thử này trên NET 4.5 RC)
- tôi có thể tái sản xuất này trên cả hai Debug/phát hành trên bất kỳ x86/x64/Bất kỳ CPU nào (trên máy x64).
- Nó tái tạo một cách nhất quán (tôi muốn được quan tâm nếu có ai không thể tái tạo nó).
- Tôi có mã cũ sử dụng BackgroundWorker - vì vậy tôi không thể dễ dàng thay đổi để không sử dụng BackgroundWorker
- Tôi đã xác nhận rằng mã trong
MyContinueWith
đang chạy trên chuỗi ui chính. - Tôi không biết chính xác lý do tại sao cuộc gọi
StartLogicalOperation
giúp gây ra sự cố, đó chỉ là những gì tôi đã thu hẹp nó xuống trong đơn đăng ký của mình.
Vâng, bạn có chẩn đoán từ liên kết đó. Bạn cũng đang trộn mã WPF hoặc WCF vào ứng dụng Winforms này? –
Không - Chỉ có dạng Winforms. –