2013-06-03 28 views
6

Dato questo codice ....Impossibile accedere al metodo non statico in contesto statico?

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

Perché mi appare l'errore, 'Impossibile accedere metodo non statico BeginInvoke nel contesto statico'?

Ho esaminato molti altri esempi su SE e molti citarono cercando di utilizzare un campo prima che l'oggetto venga creato come se stessero cercando di usare un campo non statico in modo statico, ma non capisco cosa riguarda il mio codice che sta invocando lo stesso errore.

Infine, cosa posso fare per risolvere questo problema/codice specifico?

Aggiornamento: titolo corretto per riflettere il problema con un "metodo" e non con una "proprietà". Ho anche aggiunto che la classe implementa ViewModelBase.

risposta

26

Se questo è WPF, System.Windows.Threading.Dispatcher non ha un metodo statico BeginInvoke().

Se si desidera chiamare che staticamente (questo è, senza avere un riferimento all'istanza di Dispatcher stesso), è possibile utilizzare la statica Dispatcher.CurrentDispatcher proprietà:

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

Attenzione però, che facendo questo da un il thread in background NON restituirà un riferimento al Dispatcher del "Thread UI", ma creerà invece una NUOVA istanza di Dispatcher associata a detto Thread in Background.

Un modo più sicuro per accedere alla "thread UI" s 'Dispatcher è attraverso l'uso della proprietà statica System.Windows.Application.Current:

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

Si noti che è possibile utilizzare WPF senza alcun oggetto 'Application', nel qual caso' Application.Current' è 'null', il che significa che il modo più sicuro non funzionerà. – hvd

+0

@hvd Giusto, tuttavia ciò dovrebbe accadere solo in casi eccezionali (come l'hosting del contenuto WPF in un'app winforms). In caso contrario, le normali applicazioni WPF e l'assenza di un'istanza della classe 'Application' portano molti problemi (come questo e le risorse relative alle risorse). –

+0

Certo, d'accordo. E anche in questo caso, se qualche codice ha bisogno di un oggetto 'Application', è possibile crearlo esplicitamente nel punto di ingresso, che funzionerà perfettamente. – hvd

3

È perché Dispatcher è una classe e non una proprietà. Non dovresti rendere la tua classe CalibrationViewModel una sottoclasse di qualche altra classe che ha una proprietà Dispatcher?

+0

Bene il CalibrationViewModel fa implementare un ViewModelBase per INPC e altri oggetti. –

+0

Questo non è ciò che mostra il tuo codice - public class CalibrationViewModel - non stai dichiarando alcuna implementazione dell'interfaccia lì. –

7

Modifica questo:

Dispatcher.BeginInvoke 

a questo:

Dispatcher.CurrentDispatcher.BeginInvoke 

la questione è BeginInvoke è un metodo di istanza e ha bisogno di un'istanza di accedervi. Tuttavia, la sintassi corrente sta tentando di accedere BeginInvoke in maniera static fuori la classe Dispatcher ed è quello che sta causando questo errore:

Cannot access non-static method BeginInvoke in static context

Problemi correlati