2013-06-03 30 views
6

Với mã này ....Không thể truy cập phương pháp không tĩnh trong ngữ cảnh tĩnh?

public class CalibrationViewModel : ViewModelBase 
{ 
    private FileSystemWatcher fsw; 

    public CalibrationViewModel(Calibration calibration) 
    { 
     fsw = new FileSystemWatcher 
      { 
       Path = @"C:\Users\user\Desktop\Path\ToFile\Test_1234.txt", 
       Filter = @"Test_1234.txt", 
       NotifyFilter = NotifyFilters.LastWrite 
      }; 

     fsw.Changed += (o, e) => 
      { 
       var lastLine = File.ReadAllLines(e.FullPath).Last(); 
       Dispatcher.BeginInvoke((Action<string>) WriteLineToSamplesCollection, lastLine); //line that cites error 
      }; 
    } 

    private void WriteLineToSamplesCollection(string line) 
    { 
     // do some work 
    } 
} 

Tại sao tôi nhận lỗi 'Không thể truy cập phương pháp không tĩnh BeginInvoke trong bối cảnh tĩnh'?

Tôi đã xem xét một số ví dụ khác về SE và hầu hết trích dẫn cố gắng sử dụng trường trước khi đối tượng được tạo như thể họ đang cố gắng sử dụng trường không tĩnh theo cách tĩnh, nhưng tôi không hiểu đó là về mã của tôi đang gọi cùng một lỗi.

Cuối cùng, tôi có thể làm gì để khắc phục vấn đề/mã cụ thể này?

Cập nhật: Tiêu đề cố định phản ánh vấn đề với 'phương pháp' chứ không phải 'thuộc tính'. Tôi cũng nói thêm rằng lớp thực hiện ViewModelBase.

Trả lời

26

Nếu đây là WPF, System.Windows.Threading.Dispatcher không có BeginInvoke() phương pháp tĩnh.

Nếu bạn muốn gọi đó là tĩnh (đây là, mà không cần phải một tham chiếu đến dụ Dispatcher chính nó), bạn có thể sử dụng tĩnh Dispatcher.CurrentDispatcher tài sản:

Dispatcher.CurrentDispatcher.BeginInvoke(...etc); 

Hãy nhận biết mặc dù, rằng làm điều này từ một thread nền sẽ KHÔNG trả về một tham chiếu đến Dispatcher "UI Thread", mà thay vào đó tạo một cá thể Dispatcher mới liên kết với Background Thread đã nói.

Một cách an toàn hơn để truy cập vào "UI Chủ đề" 's Dispatcher là thông qua việc sử dụng các tài sản System.Windows.Application.Current tĩnh:

Application.Current.Dispatcher.BeginInvoke(...etc); 
+0

Lưu ý rằng bạn có thể sử dụng WPF mà không có bất kỳ đối tượng 'Application' nào, trong trường hợp đó' Application.Current' là 'null', nghĩa là cách an toàn hơn sẽ không hoạt động. – hvd

+0

@hvd Phải, tuy nhiên điều đó sẽ chỉ xảy ra trong các trường hợp ngoại lệ (chẳng hạn như lưu trữ nội dung WPF trong một ứng dụng winforms). Nếu không thì các ứng dụng WPF thông thường và không có một thể hiện của lớp 'Application' sẽ mang lại rất nhiều vấn đề (như điều này, và các công cụ liên quan đến tài nguyên). –

+0

Chắc chắn, đã đồng ý. Và ngay cả trong trường hợp đó, nếu một số mã cần một đối tượng 'Application', có thể tạo một cách rõ ràng một đối tượng trong điểm vào, nó sẽ hoạt động tốt. – hvd

3

Đó là vì Dispatcher là một lớp không phải là tài sản. Bạn có nên tạo lớp học CalibrationViewModel lớp con của một số lớp khác có thuộc tính Dispatcher không?

+0

Vâng CalibrationViewModel không thực hiện một ViewModelBase cho INPC và các mặt hàng khác. –

+0

Đó không phải là những gì mã của bạn hiển thị - lớp công khai CalibrationViewModel - bạn không khai báo bất kỳ triển khai giao diện nào ở đó. –

7

Thay đổi này:

Dispatcher.BeginInvoke 

này:

Dispatcher.CurrentDispatcher.BeginInvoke 

vấn đề là BeginInvoke là một phương pháp dụ và cần một thể truy cập vào nó. Tuy nhiên, cú pháp hiện tại của bạn đang cố gắng truy cập vào BeginInvoke một cách static ra khỏi lớp Dispatcher và đó là những gì gây ra lỗi này:

Cannot access non-static method BeginInvoke in static context

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