Tôi cần phải "gửi" một đoạn mã từ một chuỗi khác (Excel Interop) đến chuỗi giao diện người dùng để thực thi. Thông thường bạn muốn sử dụng Invoke
trên Form
, mà thực hiện giao diện ISynchronizeInvoke
:Cách sử dụng ISynchronizeInvoke mà không cần tham chiếu đến Biểu mẫu
public class MyForm : Form
{
...
private void Button_Click(object sender, EventArgs e)
{
SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel)
{
this.Invoke(someCode);
};
}
}
Đáng tiếc là có một lớp trừu tượng giữa các mẫu mã và mã định nghĩa xử lý sự kiện, và tôi không có một tham chiếu đến biểu mẫu tại thời điểm đó:
public void CodeExecutedByUIThread()
{
ISynchronizeInvoke sync;
SomeExcelWorkbook.OnBeforeClose += delegate(ref bool Cancel)
{
sync.Invoke(someCode);
};
}
Khi nhập CodeExecutedByUIThread
, chúng tôi vẫn đang ở trong chuỗi giao diện người dùng, vì vậy về lý thuyết, mọi thứ cần có ở đó. Thật không may là Form is the only class implementing that interface, phải không?
Làm cách nào để nhận được ISynchronizeInvoke
từ bên trong chuỗi giao diện người dùng? Rõ ràng Thread.CurrentThread
không cung cấp ...
Hoặc có cách nào để nhận được SynchronizationContext
không? Làm thế nào tôi sẽ lấy và sử dụng nó?
Cập nhật: Ồ, tôi thấy, việc nhận đối tượng SynchronizationContext trông đơn giản như SynchronizationContext.Current
, không cần tham chiếu đến biểu mẫu. Vì vậy, tôi sẽ google thêm một chút về cách sử dụng.
Ồ, tôi thấy, việc nhận đối tượng SynchronizationContext trông khá đơn giản và do đó, nên làm việc ngay cả khi không có tham chiếu đến biểu mẫu. – chiccodoro
Hãy cẩn thận, kể từ khi sử dụng SynchronizationContext.Current trên một chủ đề thứ cấp sẽ không nhận được bối cảnh mà bạn muốn, đó là lý do tại sao tôi khuyên bạn nên lưu trữ nó từ các chủ đề chính khi khởi động ứng dụng. – matiash
Điểm tốt, đã đọc cảnh báo đó trong tài nguyên web cũng như trong thời gian đó. – chiccodoro