2012-05-04 16 views
13

Tôi thấy rất nhiều chủ đề trên google/đây trên UPDATING phần tử giao diện người dùng từ một chuỗi khác.Bạn có thể truy cập các phần tử giao diện người dùng từ một chuỗi khác không? (không được thiết lập)

Nếu tôi muốn nhận giá trị của hộp kiểm thì sao?

Tôi có thể thực hiện việc này mà không phải làm gì đặc biệt không?

+0

bạn có thể sử dụng đại biểu để làm điều đó – jorne

+4

@CodeCaster Chỉ cần thử và xem những gì hoạt động thường không giúp bạn có được mã an toàn chỉ. – hvd

+1

@hvd: Nhưng nó đáp ứng tất cả các câu hỏi đặt ra _here_. –

Trả lời

18

Chỉnh sửa: Có vẻ như tôi phải lấy lại những gì tôi đã viết trước đây. Thử như sau:

Added một textbox gọi myTextBox và cố gắng để lấy giá trị của tài sản Text:

Thread t = new Thread(
    o => 
    { 
     Thread.Sleep(2000);      
     string value = myTextBox.Text; 
     Thread.Sleep(2000); 
    }); 
t.Start(); 

Và có vẻ như ứng dụng (WPF) bị treo sau 2 giây. Sử dụng điều phối hoạt động:

Thread t = new Thread(
    o => 
    { 
     Thread.Sleep(2000); 
     myTextBox.Dispatcher.BeginInvoke(
      (Action)(() => { string value = myTextBox.Text; })); 
     Thread.Sleep(2000); 
    }); 
t.Start(); 

Vì vậy, bạn vẫn cần phải đi qua thread dispatcher khi đọc giá trị từ các thành phần GUI, ít nhất là trong WPF.

Chỉnh sửa thứ hai: Điều này trở nên tốt hơn. Dường như lặp lại thí nghiệm cho WinForms cổ điển cho thấy nó hoạt động để đọc tài sản Text mà không cần sử dụng Invoke/BeginInvoke. Điều thú vị đủ, có vẻ như cũng thiết lập các tài sản hoạt động tốt (không gọi), mặc dù tôi sẽ cược nó không phải là chủ đề an toàn và các ứng dụng không phàn nàn vì lý do nào.

Dòng dưới cùng: Bạn nên sử dụng bộ điều phối khi tương tác với các thành phần GUI từ các chủ đề khác, vì nó đảm bảo đọc/ghi được tuần tự hóa thành một chuỗi đơn và do đó bạn không có chủ đề an toàn vấn đề.

+0

+1 để đăng thử nghiệm. –

+0

"Ứng dụng không phàn nàn" -> Chạy trong chế độ Phát hành có lẽ? –

+0

@ Henk Holterman: Tôi đã thử cả Bản phát hành và Gỡ lỗi và dường như không nhận thấy bất kỳ sự khác biệt nào. – Tudor

0

chỉ cần đọc giá trị như bình thường. Chỉ để cập nhật điều khiển, bạn cần chuyển sang giao diện GUI.

+1

lẽ làm việc với CheckBox.Checked 'cos đó là một tài sản boolean. Như những người khác đã đăng, nhận được textbox.Text là rất nhiều tinh ranh hơn. –

2

Bạn hoàn toàn có thể không an toàn. Ví dụ: Ví dụ: nếu thuộc tính Nhận mã sẽ bao gồm nhiều thao tác, chuỗi giao diện người dùng có thể hoạt động trong thời gian trung bình, nửa chừng trong khi thực hiện Lấy, gây ra các kết quả không mong muốn.

7

Bạn có thể truy cập các phần tử giao diện người dùng từ một chuỗi khác không? (không được thiết lập)?

số

Đây là thỏa thuận này. Các phần tử giao diện người dùng có các yêu cầu về mối quan hệ chặt chẽ trong luồng. Điều này có nghĩa là bạn chỉ có thể truy cập phần tử từ chuỗi lưu trữ nó. Điều này bao gồm tất cả các loại truy cập bao gồm cả lần đọc đơn giản.

Nó có thể hoạt động tốt đối với các bản ghi tài sản đơn giản, nhưng sự an toàn của nó sẽ là kết quả ngẫu nhiên của cách kiểm soát cụ thể được thực hiện. Vì Control trường hợp có ái lực chủ đề, chúng có khả năng có thể sử dụng các kỹ thuật lưu trữ cục bộ luồng để lưu một số trạng thái của chúng, tất nhiên, sẽ không tương thích với các luồng khác nhau. Hoặc nếu giá trị bạn đang cố đọc ở trạng thái nửa nướng thì sao? Sẽ không có cách nào để đồng bộ hóa quyền truy cập vào đọc đó vì ghi có thể xảy ra bên trong mã mà bạn không có quyền kiểm soát.Và vẫn còn điều này là bỏ qua các vấn đề rào cản bộ nhớ tinh tế có thể phát sinh.

Một lần nữa, nếu nó xuất hiện để làm việc sau đó phấn nó lên như một tai nạn. Truy cập các phần tử giao diện người dùng từ một chủ đề so với chủ đề lưu trữ chúng là một công thức cho thảm họa. Những điều có thể thất bại không thể đoán trước và ngoạn mục.


Có rất ít trường hợp ngoại lệ cho quy tắc này. Sử dụng các phương thức ISynchronizeInvoke là một ngoại lệ như vậy.

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