2013-06-03 19 views
6

Biorąc pod uwagę ten kod ....Nie można uzyskać dostępu do metody niestatycznej w kontekście statycznym?

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 
    } 
} 

Dlaczego otrzymuję błąd „nie można uzyskać dostępu do metody niestatyczny BeginInvoke w kontekście statyczne”?

Przyjrzałem się kilku innym przykładom na temat SE i większość cytuje próbę użycia pola, zanim obiekt zostanie utworzony, tak jakby próbowali użyć statycznego pola niestatycznego, ale nie rozumiem co chodzi o to, że mój kod wywołuje ten sam błąd.

Wreszcie, co mogę zrobić, aby rozwiązać ten konkretny problem/kod?

Aktualizacja: Naprawiono tytuł odzwierciedlający problem z "metodą", a nie "właściwością". Dodałem także, że klasa implementuje ViewModelBase.

Odpowiedz

26

Jeśli jest to WPF, System.Windows.Threading.Dispatcher nie ma statycznego BeginInvoke() metody.

Jeśli chcesz zadzwonić, że statycznie (to jest, bez odniesienia do samej instancji Dispatcher), można użyć statycznej Dispatcher.CurrentDispatcher właściwość:

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

zdawać sobie sprawę jednak, że robi to z wątek tła NIE zwróci odwołania do "Dispatchera" wątku UI, ale zamiast tego utworzy nową instancję Dispatchera powiązaną ze wspomnianym wątkiem tła.

Bardziej bezpieczny sposób uzyskać dostęp do „UI wątek” 's Dyspozytor jest poprzez wykorzystanie własności statyczne System.Windows.Application.Current:

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

Należy zauważyć, że można używać WPF bez obiektu "Application", w którym to przypadku 'Application.Current' ma wartość' null', co oznacza, że ​​bezpieczniejsza metoda nie będzie działać. – hvd

+0

@hvd Tak, jednak powinno się to zdarzyć tylko w wyjątkowych przypadkach (np. Hostowanie treści WPF w aplikacji WinForm). W przeciwnym razie przechodzenie do zwykłych aplikacji WPF i brak instancji klasy "Application" niesie ze sobą wiele problemów (takich jak ten i związanych z zasobami). –

+0

Pewnie, zgodzili się. I nawet w takim przypadku, jeśli jakiś kod potrzebuje obiektu 'Application', możliwe jest jawne utworzenie go w punkcie wejścia, co będzie działało dobrze. – hvd

3

To dlatego, że Dispatcher to klasa, która nie jest własnością. Czy nie powinieneś tworzyć klasy podklasy innej klasy, która ma właściwość Dispatcher?

+0

Dobrze CalibrationViewModel robi wdrożyć ViewModelBase dla INPC i innych przedmiotów. –

+0

To nie jest to, co pokazuje twój kod - public class CalibrationViewModel - nie deklarujesz tam implementacji interfejsu. –

7

Zmień to:

Dispatcher.BeginInvoke 

do tego:

Dispatcher.CurrentDispatcher.BeginInvoke 

problem jest BeginInvoke jest metoda instancji i wymaga wystąpienia do niego dostęp. Jednak aktualna składnia próbuje uzyskać dostęp BeginInvoke w static sposób off klasy Dispatcher i to, co jest przyczyną tego błędu:

Cannot access non-static method BeginInvoke in static context

Powiązane problemy