2015-07-29 9 views
9

मैं इसे पूरा होने पर Task फिर से चला रहा हूं। नीचे वह कार्य है जिसे मैं अपने आवेदन के Application_Start में कॉल करता हूं।सी # में एकाधिक कार्यों को कैसे चलाएं और इन कार्यों को पूरा करने पर कोई ईवेंट प्राप्त करें?

private void Run() 
{ 
    Task t = new Task(() => new XyzServices().ProcessXyz()); 
    t.Start(); 
    t.ContinueWith((x) => 
    { 
     Thread.Sleep(ConfigReader.CronReRunTimeInSeconds); 
     Run(); 
    }); 
} 

मैं कई कार्यों को चलाने के लिए चाहता हूं, संख्या जो web.config ऐप सेटेटिंग से पढ़ी जाएगी।

मैं कुछ इस तरह कोशिश कर रहा हूँ,

private void Run() 
{ 
    List<Task> tasks = new List<Task>(); 
    for (int i = 0; i < ConfigReader.ThreadCount - 1; i++) 
    { 
     tasks.Add(Task.Run(() => new XyzServices().ProcessXyz())); 
    } 

    Task.WhenAll(tasks); 

    Run(); 
} 

क्या सही तरीका यह करने के लिए?

+0

अगर आप/अपनी खुद की taskrunner निर्माण उस वर्ग मैं शायद पहला काम का उपयोग करके समाप्त होने की प्रतीक्षा करता हूँ विस्तृत करने खुदाई करने के लिए नहीं करना चाहते हैं 'tasks.First()। प्रतीक्षा करें(); 'और फिर थ्रेड के साथ थोड़ी देर लूप का उपयोग करें। शेष कार्यों की स्थिति का निरीक्षण करने के लिए सो जाओ। –

+1

आप पूर्व निर्धारित समय अंतराल में बार-बार कोड का एक टुकड़ा चलाने के लिए चाहते हैं? सटीक कारण की तरह लगता है कि 'टाइमर' वास्तव में मौजूद है। और निश्चित रूप से, यदि आप इसके साथ रहना चाहते हैं, तो बस 'कार्य' के परिणाम के लिए अपनी निरंतरता को बाध्य करें। सब कुछ और सबकुछ पहले जैसा ही काम करेगा। – Luaan

+0

आपको या तो 'कार्य का इंतजार करना होगा। जब सभी (कार्य); 'या' कार्य। प्रतीक्षा करें (कार्य); '। एक एसिंक कॉल है और इसकी प्रतीक्षा की जानी चाहिए, दूसरा एक सामान्य कार्य है जिसे एक तुल्यकालिक संदर्भ में बुलाया जा सकता है। बेशक आप बदसूरत 'कार्य के लिए भी जा सकते हैं। जब सभी (कार्य) .Wait();' – Dorus

उत्तर

13

मेरा मानना ​​है कि आप देख रहे हैं:

Task.WaitAll(tasks.ToArray()); 

https://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx

+1

आप 'ToArray() ' – Amit

+0

पर कॉल खो रहे हैं! बस मुझे क्या चाहिए। – Yasser

+1

@ यहां उपयोग की गई सूची के बीच एक विसंगति दर्ज करें, और उदाहरण में उपयोग की जाने वाली सरणी, धन्यवाद :) –

1

आप समाप्त करने के लिए सभी कार्य प्रतीक्षा करें और उन्हें फिर पुन: प्रारंभ करना चाहते हैं, मार्क्स का जवाब सही है।

लेकिन अगर आप चाहते हैं THREADCOUNT कार्य,

void Run() 
{ 
    SemaphoreSlim sem = new SemaphoreSlim(ConfigReader.ThreadCount); 

    Task.Run(() => 
    { 
     while (true) 
     { 
      sem.Wait(); 
      Task.Run(() => { /*Your work*/ }) 
       .ContinueWith((t) => { sem.Release(); }); 
     } 
    }); 
} 
+0

आंतरिक' कार्य 'रून क्यों? आप एक थ्रेड अवरुद्ध कर रहे हैं जबकि दूसरे को सिंक्रनाइज़ेशन चलाने के लिए उपयोग किया जाता है। बस 'sem.Wait() का उपयोग करें; कोशिश करें {RunWhatever(); } अंत में {sem.Release(); } '। – Luaan

+0

@Luaan No यह नहीं है कि मैं अपने कोड के साथ क्या करना चाहता हूं। मैं एक काम खत्म करने की प्रतीक्षा नहीं कर रहा हूं, फिर एक नया शुरू करें। जब भी उनमें से एक खत्म होता है तो मैं सिर्फ एक नया काम करता हूं। तो हमेशा * थ्रेडकाउंट * कार्य चलेंगे .. – EZI

+0

कार्य नहीं करता है।जब सभी थ्रेडपूल का उपयोग करते हैं जो दूसरों को कतार में स्वचालित रूप से 'सर्वोत्तम' कार्यों को स्वचालित रूप से चलाता है? –

8

किसी भी समय चल रहा हो (जैसे ही कोई नया कार्य शुरू के रूप में उनमें से किसी एक समाप्त होता है) तो अगर आप के बाद कार्य एक चलाना चाहते हैं अन्य,

await Task.Run(() => new XyzServices().ProcessXyz()); 
await Task.Delay(ConfigReader.CronReRunTimeInSeconds * 1000); 

अगर तुम उन्हें समवर्ती चलाने के लिए, कार्य अनुसूचक परमिट के रूप में चाहते हैं,

await Task.WhenAll(new[] 
    { 
     Task.Run(() => new XyzServices().ProcessXyz()), 
     Task.Run(() => new XyzServices().ProcessXyz()) 
    }); 

तो, अपने विधि, की तरह कुछ होना चाहिए

private async Task Run() 
{ 
    var tasks = 
     Enumerable.Range(0, ConfigReader.ThreadCount) 
     .Select(i => Task.Run(() => new XyzServices().ProcessXyz())); 

    await Task.WhenAll(tasks); 
} 
+0

मैंने पहले पढ़ा था कि कार्यों का इंतजार करना उनके निष्पादन को शुरू नहीं करता है, कि वे वास्तव में तुरंत या वहां शुरू होते हैं। क्या ये सही है? यह आपके पहले बयान जटिल करेगा। –

+0

@ बेनकनोबल, यह एक उचित बिंदु है, मैंने स्पष्ट किया है। – Jodrell

+0

यदि आप जिन फ़ंक्शंस को कॉल कर रहे हैं वे स्वयं एसिंक हैं, तो आपको उन्हें 'टास्क.रुन' में लपेटने की आवश्यकता नहीं है। हालांकि, यह महसूस करना महत्वपूर्ण है कि एसिंक कार्य वर्तमान थ्रेड पर तुरंत शुरू हो जाएगा, और एक बार एसिंक कॉल में चलाए जाने के बाद केवल संदर्भ स्विच करें। सीपीयू भारी कार्यों के लिए आपको निश्चित रूप से उन कार्यों के लिए 'टास्क.रुन' में लपेटना चाहिए, जो जल्दी से एसिंक कॉल (आमतौर पर आईओ) पर स्विच करते हैं, आपको उन्हें लपेटकर बेहतर प्रदर्शन मिलता है। – Dorus

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