2010-06-17 13 views
6

का उपयोग करते हुए कहते हैं मैं करते पृष्ठभूमि कार्यकर्ता चल रहा है इस तरह एक पृष्ठभूमि कार्यकर्ता:कैसे शुरू करने और बंद करो एक लगातार एक बटन

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      while(true) 
      { 
        //Kill zombies 
      } 
     } 

मैं इस पृष्ठभूमि कार्यकर्ता शुरुआत कैसे कर सकता हूँ और एक WinForm पर एक बटन का उपयोग बंद कर सकते हैं?

+3

हम्म, जवाब में स्वीकार कर लिया, सावधान रहना के लिए - आप एक प्रभाव है कि केवल यह कारण एक यात्रा को रोकने के लिए नहीं होगा के बारे में सभी में चिंता कर रहे हैं या दो बाद में, लेकिन भूल गए कि आप एक पूरे प्रोसेसर बस कताई बनाने जा रहे हैं! कम से कम वहां सो जाओ। ऐसा लगता है कि यह काम कर रहा है लेकिन बड़ी हानि के लिए।कुछ अन्य उत्तरों उन सभी समस्याओं को हल करते हैं जिनसे आप उन्हें हल करने के लिए 'अनुमानित' हैं। – FastAl

उत्तर

5
+0

ठीक काम करता है: डी – sooprise

+0

"एक बूल एक्सेस करना और अपडेट करना एक परमाणु ऑपरेशन है"। क्या यह स्मृति बाधा के कारण है? –

+0

नहीं, परमाणु का अर्थ है कि मूल्य एक वास्तविक में गलत या गलत लिखा जाएगा। एक मेमोरी बाधा उस ऑर्डर को निर्देशित करती है जो मूल्य के लिखते या पढ़ती है उसे किसी अन्य थ्रेड द्वारा देखा जाता है। ऐसा कुछ भी नहीं है जो कहता है कि _performKilling को लिखा गया मान कभी भी इस तरह के तंत्र के बिना किसी अन्य धागे में दिखाई देगा। परमाणुता का अर्थ है कि मान पढ़ना हमेशा सत्य या गलत होगा, इसका मतलब यह नहीं है कि पृष्ठभूमि धागा कभी हाल ही में लिखित मूल्य को देखेगा। –

0

मैं इस परीक्षण किया है नहीं, मैंने कहीं कोड है कि मुझे लगता है मैं वास्तव में क्या किया था देखने के लिए होगा, लेकिन कुछ इस तरह फ्रेड्रिक के जवाब का रूपांतरण है:

private bool _performKilling; 
private object _lockObject = new object(); 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while(true) 
    { 

     if (_performKilling) 
     { 
      //Kill zombies 
     } 
     else 
     { //We pause until we are woken up so as not to consume cycles 
      Monitor.Wait(_lockObject); 
     } 
    } 
} 

private void StartKilling() 
{ 
    _performKilling = true; 
    Monitor.Pulse(_lockObject); 
} 

private void StopAllThatKilling() 
{ 
    _performKilling = false; 
] 

इस पैटर्न यहाँ की अधिक पूर्ण उदाहरण:

https://github.com/AaronLS/CellularAutomataAsNeuralNetwork/blob/fe9e6b950e5e28d2c99350cb8ff3157720555e14/CellLifeGame1/Modeling.cs

+0

आह, ज़ाहिर है; अच्छा समाधान मुझे शुरुआत से ही इसके साथ आने के लिए थक जाना चाहिए;) –

+0

_ "मैंने इसका परीक्षण नहीं किया है" _ - स्पष्ट रूप से, क्योंकि 'प्रतीक्षा करें()' और 'पल्स()' पर कॉल अपवाद फेंक देंगे, क्योंकि आपने उन विधियों को कॉल करने से पहले मॉनीटर नहीं लिया है। –

+0

@ पीटर ड्यूनिहो बेशक यहां कुछ नलसाजी नहीं दिख रही हैं। इसका मतलब यह था कि मॉनिटर पर कुछ विधियों को रोकना/रोकना आसान था। यहां अधिक पूर्ण उदाहरण: https://github.com/AaronLS/CellularAutomataAsNeuralNetwork/blob/fe9e6b950e5e28d2c99350cb8ff3157720555e14/CellLifeGame1/Modeling.cs – AaronLS

17

हो सकता है कि आप इस, मैं di तरह एक ManualResetEvent उपयोग कर सकते हैं इसे डीबग नहीं करें लेकिन एक शॉट के लायक है। यह आप जबकि यह

ManualResetEvent run = new ManualResetEvent(true); 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    while(run.WaitOne()) 
    { 
     //Kill zombies 
    } 
} 

private void War() 
{ 
    run.Set(); 
} 

private void Peace() 
{ 
    run.Reset(); 
} 
+0

+1 यह एक और आत्मा को देखने के लिए बहुत अच्छा है जो वास्तव में .NET थ्रेडिंग को समझता है। ;) मुझे लगता है कि इन स्थितियों में एक वेटहैंडल का उपयोग हमेशा बेहतर विकल्प होता है, क्योंकि वे आंतरिक रूप से आपके लिए परमाणुता और अन्य बहुप्रचार मुद्दों का ख्याल रखते हैं (मानते हैं कि आप सही प्रकार का वेटहैंडल चुनते हैं)। – jrista

+0

'जबकि (सच) {if (run.WaitOne()) {}}'? थोड़ा अनावश्यक लगता है, है ना? क्यों नहीं (run.aitOne()) {} '? –

+0

यह वास्तव में है, मैंने सोचा कि पोस्टिंग के बाद, मैं इसे –

7

CancelAsync विधि का उपयोग करें इंतजार कर रहा है धागा अपने चक्रों को घुमाना नहीं होने दिया जाएगा काम करता है।

backgroundworker1.CancelAsync(); 

कार्यकर्ता धागे के अंदर अपने पाश में।

if (backgroundWorker.CancellationPending) return; 

यह तुरंत नहीं होता है।

+5

+1 अपडेट कर दूंगा: मुझे नहीं पता कि हर कोई 'while (_someCustomBoolean)' की जांच क्यों कर रहा है, जब 'BackgroundWorker' क्लास में पहले से ही इस कार्यक्षमता का निर्माण किया गया है। –

+1

लंबित रद्दीकरण सेट होने पर, मुझे लगता है कि सामान्य प्रोटोकॉल पृष्ठभूमि कार्यकर्ता के लिए रुकने और पूरा करने के लिए है। इस स्थिति में मेरा मानना ​​है कि प्रश्न शुरू करने और रोकने के लिए एक रास्ता मांग रहे थे। पृष्ठभूमि कार्यकर्ता भी आपको यात्रा कर सकता है। यदि आप इसकी अपूर्ण घटना का उपयोग करते हैं, तो यह .NET जेनेरिक थ्रेडपूल के माध्यम से पोस्ट हो जाता है, मैंने इस डेडलॉक को पहले और वहां फेंकने के आधार पर देखा है। –

4

स्टॉप द्वारा आप वास्तव में बंद करना चाहते हैं या क्या आपका मतलब रोकना है? यदि आपका मतलब बंद है, तो यह केक का एक टुकड़ा है। उस बटन के लिए बटन बटन इवेंट हैंडलर बनाएं जिसे आप पृष्ठभूमि कार्यकर्ता शुरू करने के लिए ज़िम्मेदार होना चाहते हैं और बटन को इवेंट हैंडलर को रोकने के लिए ज़िम्मेदार व्यक्ति के लिए क्लिक करें। अपने स्टार्ट बटन पर, पृष्ठभूमि कार्यकर्ता विधि पर कॉल करें जो do_work ईवेंट को सक्रिय करता है। कुछ इस तरह:

private void cancelAsyncButton_Click(System.Object sender, 
    System.EventArgs e) 
{ 
    // Cancel the asynchronous operation. 
    this.backgroundWorker1.CancelAsync(); 
} 

अब मत भूलना के लिए जाँच करने के लिए: अपने स्टॉप बटन पर

private void startButton_Click(System.Object sender, 
    System.EventArgs e) 
{ 
    // Start the asynchronous operation. 
    backgroundWorker1.RunWorkerAsync(); 
} 

, विधि सेट कि पृष्ठभूमि कार्यकर्ता CancellationPending सच करने के लिए, इस तरह के एक फोन करना CancelationPending आपके पृष्ठभूमि कार्यकर्ता के doWork के अंदर ध्वज। कुछ इस तरह:

private void KillZombies(BackgroundWorker worker, DoWorkEventArgs e) 
    { 
     while (true) 
     { 
      if (worker.CancellationPending) 
      { 
       e.Cancel = true; 
      } 
     } 
    } 

और अपने doWork विधि:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      BackgroundWorker worker = sender as BackgroundWorker; 
      KillZombies(worker, e); 
     } 

मुझे आशा है कि यह सही दिशा में ले जा सकते हैं। कुछ आगे रीडिंग:

http://msdn.microsoft.com/en-us/library/b2zk6580(v=VS.90).aspx

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

http://msdn.microsoft.com/en-us/library/waw3xexc.aspx

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