2011-11-03 3 views
9

मेरे पास एक थ्रेड है जो कुछ प्रोसेसिंग कर रहा है। मैं निष्पादन के दौरान इस धागे को रोकने में सक्षम होना चाहूंगा, किसी भी तरह से इसकी स्थिति (और जिस वस्तु पर यह चल रहा है) की स्थिति को बचाएं, और फिर उस स्थान से बाद की तारीख में जारी रखें (इसलिए मेरे कंप्यूटर को पुनरारंभ करने के बाद)।निष्पादन के दौरान मैं कैसे रोकूं, राज्य को सहेजूं, और बाद में उसी बिंदु से जारी रहूं?

सी # में यह संभव सही नहीं है? और यदि नहीं, तो इस कार्यक्षमता को प्राप्त करने के लिए उचित डिजाइन क्या है?

तो अपने मूल इच्छा

class Foo : Task { 
    void override Execute(){ 
     //example task 
     while(someCondition){ 
     ...do stuff... 
     } 
    } 
} 

की तरह कुछ है तथा रोकें/कि समारोह के किसी भी समय को बचाने के लिए सक्षम होने के लिए किया गया था। जब कार्य समाप्त होता है, तो हर कोई जानता है कि यह पूरा हो गया है। एक विकल्प के रूप में, शायद यह यह

class Foo : Task { 


    void override Execute(State previousState){ 
     //set someCondition, other stuff 
     //IsPaused = false; 
     previousState.setUpStuff(); 

     //example task 
     while(someCondition){ 
      ...do stuff... 
      if(base.IsPauseRequested){ 
       base.UpdateState(); //this would be a bit different but just to get the idea 
       base.IsPaused = true; 
       return; 
      } 
     } 

     base.RaiseNotifyTaskComplete(); 
    } 

} 

करने के लिए बेहतर तरीका तो पहले मामले अन्य लोगों को जो मेरी आधार वर्ग के वारिस के रूप में वे केवल निष्पादित समारोह को लागू करने के लिए है की जरूरत के लिए बहुत आसान है। हालांकि, दूसरे मामले में, उन्हें पिछले राज्य पर विचार करना होगा और यह भी प्रबंधित करना होगा कि अच्छे विराम बिंदु कहां मौजूद हैं। क्या ऐसा करने के लिए इससे अच्छा तरीका है?

उत्तर

4

तुम क्या चाहते एक serializable राज्य मशीन द्वारा पूरा किया जा सकता है। असल में, आप अपने स्थानीय चर को कक्षा में फ़ील्ड में बदलते हैं और एक फ़ील्ड जोड़ते हैं जो राज्य को रखता है - मूल विधि के कोड में स्थिति। यह कक्षा [Serializable] होगी और इसमें MoveNext() जैसी एक विधि होगी, जो काम और रिटर्न का एक टुकड़ा है। काम करते समय, आप इस विधि को लूप में कॉल करते हैं। जब आप रुकना चाहते हैं, तो आप वर्तमान कॉल समाप्त होने तक प्रतीक्षा करें, लूप से बाहर निकलें और फिर राज्य मशीन को डिस्क पर क्रमबद्ध करें।

मूल विधि की जटिलता और आप कितनी बार "चेकपॉइंट" करना चाहते हैं (जब MoveNext() विधि रिटर्न और आप जारी रखना चुन सकते हैं या नहीं), राज्य मशीन केवल एक राज्य के रूप में सरल हो सकती है , या काफी जटिल।

सी # कंपाइलर बहुत ही समान परिवर्तन करता है जब यह इटरेटर ब्लॉक (और सी # 5 के async विधियों) को संकलित करता है। लेकिन यह इस उद्देश्य के लिए नहीं है और यह जेनरेटेड क्लास [Serializable] को चिह्नित नहीं करता है, इसलिए मुझे नहीं लगता कि आप इसका उपयोग कर सकते हैं। यद्यपि यह परिवर्तन वास्तव में कैसे किया जाता है, इस बारे में कुछ लेख पढ़ना आपको ऐसा ही करने में मदद कर सकता है।

0

मैं C# के लिए उत्तर नहीं दे सकता, लेकिन आम तौर पर इस प्रश्न को Persistence कहा जाता है और इसे हल करने के लिए कोई सामान्य आसान तरीका नहीं है (जब तक कि भाषा और सिस्टम इसे प्रदान नहीं करता)। आप एक थ्रेड के मामले में कारण नहीं दे सकते हैं, क्योंकि जिस थ्रेड पर आप विचार कर रहे हैं वह कुछ अन्य (वैश्विक या ढेर) डेटा का संदर्भ दे रहा है। यह प्रश्न garbage collection से भी संबंधित है (क्योंकि कचरा कलेक्टर और दृढ़ता तंत्र दोनों पूरे लाइव ढेर को स्कैन करते हैं)।

0

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

+0

यह एक अच्छा विचार है और मैं इस तरह के बारे में सोच रहा था ... लगभग एक सरणी जो फंक्शन पॉइंटर्स (प्रतिनिधि) से भरा है। तो मैं सिर्फ सरणी के साथ एक सूचक ले जाएँ। इस विचार के साथ मेरा मुद्दा यह है कि मैं चाहता हूं कि मेरी बेस क्लास अन्य लोगों द्वारा उपयोग की जाए। मुझे लगता है कि ऐसा कुछ करने से स्थिति जटिल हो जाएगी (क्योंकि बहुत से लोगों के पास केवल ऐसे कार्य होंगे जिनमें सरणी में केवल एक फ़ंक्शन पॉइंटर होगा)। हालांकि मुझे यह विचार पसंद है। – i8abug

0

आप जब प्रक्रिया रोक दिया गया है अपने वस्तु की स्थिति को क्रमानुसार करने, और फिर deserialize यह एक बार वह पुन: प्रारंभ करना चाहते हैं।

एक बहुत भोली कार्यान्वयन जो Linq का उपयोग पढ़ने/XML में अपनी वस्तु की स्थिति लिखने के लिए अपने कार्य वर्ग को क्रमानुसार/deserialize पर दो स्थिर तरीकों बनाने के लिए किया जाएगा। जब कोई कार्य रोक दिया जाता है तो Serialize जो ऑब्जेक्ट को डिस्क पर xml के रूप में डंप करता है, जब इसे पुनरारंभ किया जाता है तो Deserialize जो xml को पढ़ता है। XmlSerializer कक्षा भी है जो अधिक मजबूत हो सकती है।

बावजूद यह एक जटिल समस्या है, एक धारणात्मक सरल समाधान के साथ।

+0

ऐसा लगता है कि आप मूल रूप से उस विधि का समर्थन कर रहे हैं जो मेरे पास IsPaused चर के साथ है, है ना? मैंने इस बारे में बहुत कुछ नहीं सोचा है कि मैं धारावाहिक कैसे करूंगा लेकिन शायद आप जैसे कुछ कहें। मैं उम्मीद कर रहा था कि ऐसा करने का एक बेहतर तरीका होगा लेकिन शायद इस स्थिति से निपटने के लिए मानक तरीका है। – i8abug

+0

हुक या क्रूक द्वारा आपको ऑब्जेक्ट स्थिति को सहेजने की आवश्यकता होगी यदि आप इसे रोकना चाहते हैं, और बाद में वापस आएं। तो, हाँ, जब आप 'setupStuff' कहां कॉल करते हैं तो आप रुकने और deserialize जब आप serialize करेंगे – Jason

1

इसे डब्ल्यूएफ का उपयोग करके आसानी से हासिल किया जा सकता है ... इसमें स्पष्ट रूप से रोकें और फिर से शुरू करने के लिए सभी नलसाजी हैं (और यह आपके लिए दृढ़ता का ख्याल रखती है)। Check out this link.

शायद आप जो चाहते हैं उसके लिए उपयुक्त नहीं हो, लेकिन शायद जांच के लायक हो।

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

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