2013-06-03 6 views
6

इस कोड को देखते हुए ....स्थिर संदर्भ में गैर स्थैतिक विधि का उपयोग नहीं कर सकते हैं?

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

क्यों मैं त्रुटि हो रही है, 'स्थिर संदर्भ में गैर स्थैतिक विधि BeginInvoke तक नहीं पहुंच पा'?

मैंने एसई पर कई अन्य उदाहरणों को देखा है और ऑब्जेक्ट बनने से पहले एक फ़ील्ड का उपयोग करने की कोशिश कर रहे अधिकांश उद्धरण जैसे कि वे एक स्थैतिक तरीके से एक गैर स्थैतिक क्षेत्र का उपयोग करने की कोशिश कर रहे थे, लेकिन मुझे समझ में नहीं आता कि क्या यह मेरे कोड के बारे में है जो एक ही त्रुटि का आह्वान कर रहा है।

आखिरकार, मैं इस विशिष्ट समस्या/कोड को ठीक करने के लिए क्या कर सकता हूं?

अद्यतन: 'विधि' के साथ समस्या को प्रतिबिंबित करने के लिए निश्चित शीर्षक और 'संपत्ति' नहीं। मैंने यह भी कहा कि कक्षा ViewModelBase लागू करती है।

उत्तर

26

यदि यह WPF है, System.Windows.Threading.Dispatcher एक स्थिर BeginInvoke() विधि नहीं है।

आपको लगता है कि स्थिर कॉल करने के लिए (यह है, डिस्पैचर उदाहरण खुद के लिए एक संदर्भ के बिना) चाहते हैं, आप स्थिर Dispatcher.CurrentDispatcher संपत्ति का उपयोग कर सकते हैं:

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

हालांकि ध्यान रखें, कि एक से यह कर पृष्ठभूमि धागा "यूआई थ्रेड" के प्रेषक के संदर्भ को वापस नहीं करेगा, बल्कि इसके बजाय पृष्ठभूमि पृष्ठभूमि थ्रेड से जुड़े एक नया डिस्पैचर उदाहरण बनाएं।

एक अधिक सुरक्षित तरीके System.Windows.Application.Current स्थिर संपत्ति के उपयोग के माध्यम से "यूआई थ्रेड" के डिस्पैचर है तक पहुँचने के लिए:

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

ध्यान दें कि आप किसी भी 'एप्लिकेशन' ऑब्जेक्ट के बिना WPF का उपयोग कर सकते हैं, जिस स्थिति में 'Application.Current' 'null' है, जिसका अर्थ है कि अधिक सुरक्षित तरीका काम नहीं करेगा। – hvd

+0

@ एचवीडी राइट, हालांकि यह केवल असाधारण मामलों में होना चाहिए (जैसे Winforms ऐप में WPF सामग्री होस्ट करना)। अन्यथा नियमित WPF अनुप्रयोगों पर जा रहे हैं और 'एप्लिकेशन' कक्षा का उदाहरण नहीं होने से बहुत सारे मुद्दे सामने आते हैं (जैसे कि, और संसाधन-संबंधित सामान)। –

+0

निश्चित रूप से, सहमत हुए। और यहां तक ​​कि उस स्थिति में, अगर कुछ कोड को 'एप्लिकेशन' ऑब्जेक्ट की आवश्यकता होती है, तो प्रवेश बिंदु में स्पष्ट रूप से एक बनाना संभव है, जो ठीक काम करेगा। – hvd

3

यह क्योंकि Dispatcher एक वर्ग नहीं एक संपत्ति है। क्या आप अपनी CalibrationViewModel कक्षा किसी अन्य वर्ग के उप-वर्ग को नहीं बना सकते हैं जिसमें Dispatcher संपत्ति है?

+0

खैर CalibrationViewModel INPC और अन्य मदों के लिए एक ViewModelBase को लागू करता है। –

+0

यह नहीं है कि आपका कोड क्या दिखाता है - पब्लिक क्लास कैलिब्रेशन व्यू मॉडेल - आप वहां कोई इंटरफ़ेस कार्यान्वयन घोषित नहीं कर रहे हैं। –

7

बदलें इस:

Dispatcher.BeginInvoke 
इस के लिए

:

Dispatcher.CurrentDispatcher.BeginInvoke 

मुद्दा BeginInvoke है एक उदाहरण विधि है और इसे उपयोग करने में एक उदाहरण की जरूरत है। हालांकि, अपने वर्तमान वाक्य रचना वर्ग Dispatcher बंद एक static ढंग से BeginInvoke का उपयोग करने की कोशिश कर रहा है और वह है क्या जिसके कारण त्रुटि है:

Cannot access non-static method BeginInvoke in static context

संबंधित मुद्दे