2016-10-17 10 views
6

सी # में एक असीमित समसामयिक तरीका है? जहां आईडी (रों) के बजाय का उपयोग कर Parallel.ForEachअसिंक्रोनस फोरैच

//This Gets all the ID(s)-IEnumerable <int> 
var clientIds = new Clients().GetAllClientIds(); 

Parallel.ForEach(clientIds, ProcessId); //runs the method in parallel 

static void ProcessId(int id) 
{ 
// just process the id 
} 

कुछ एक foreach होना चाहिए की विधि द्वारा अतुल्यकालिक रूप से कार्रवाई की जाएगी, लेकिन

foreach(var id in clientIds) 
{ 
    ProcessId(id) //runs the method with each Id asynchronously?? 
} 

एसिंक्रोनस रूप से चलाता है मैं चलाने के लिए कोशिश कर रहा हूँ कंसोल में कार्यक्रम, कंसोल बंद करने से पहले सभी आईडी (ओं) को प्रसंस्करण पूर्ण करने के लिए प्रतीक्षा करनी चाहिए।

+0

तरह से किया जा होगा तुम यहाँ सुनिश्चित नहीं हैं कि क्या कह रहे हैं के लिए होगा। मुझे लगता है कि आप एक बहु थ्रेडेड फोरैच के लिए पूछ रहे हैं लेकिन आप 'समानांतर' फोरेच '(जो बहु-थ्रेडेड हैं) का उपयोग नहीं करना चाहते हैं? – Igor

+0

ठीक है, क्या आपका 'ProcessId' फ़ंक्शन दूसरे उदाहरण में असीमित है? क्या यह एक 'कार्य' वापस करता है? आप केवल "एसिंक्रोनस फ़ंक्शन" नहीं कर सकते हैं, आपको इसे अतुलनीय रूप से लिखना है या इसे किसी अन्य थ्रेड पर निष्पादित करना है (जैसे 'समांतर। फोरएच' करता है) –

+4

@ इगोर 'समानांतर। फॉरएच' असीमित नहीं है, यह समकालिक रूप से समानांतर में कार्यों को संसाधित करता है । इसके अलावा यह async/प्रतीक्षा का समर्थन नहीं करता है, इसलिए दोनों को मिश्रण करने से सावधान रहें। –

उत्तर

12

नहीं, यह वास्तव में संभव नहीं है।

बजाय फ़ोरैच लूप में आप कार्य संग्रह के लिए कार्य के रूप में क्या करना चाहते हैं और बाद में कार्य का उपयोग करें। प्रतीक्षा करें।

var tasks = new List<Task>(); 

foreach(var something in somethings) 
tasks.Add(DoJobAsync(something)); 

await Task.WhenAll(tasks); 

ध्यान दें कि विधि DoJobAsync को कार्य वापस करना चाहिए।

अद्यतन:

अपने विधि टास्क लेकिन कुछ और (जैसे शून्य) आपके पास दो विकल्प है, जो मूलतः एक ही हैं है वापस नहीं करता है, तो: करने के लिए

1.Add Task.Run (कार्रवाई) कार्य संग्रह बजाय

tasks.Add(Task.Run(() => DoJob(something))); 

2.Wrap अपने विधि में सिंक विधि टास्क

private Task DoJobAsync(Something something) 
{ 
    return Task.Run(() => DoJob(something)); 
} 
लौटने

यदि आप कार्य निष्पादन से कुछ परिणाम प्राप्त करना चाहते हैं तो आप Task<TResult> सामान्य भी उपयोग कर सकते हैं।

+0

क्या यह वास्तव में इसे असीमित रूप से चलाएगा? मैं इसे अभी तक अपने कोड पर दोहराने की कोशिश कर रहा हूं, ऐसा लगता है कि मेरे सभी DoJobAsync उदाहरण एक दूसरे के बाद दौड़ते हैं। – Anzurio

6

आपका लक्ष्य विधि एक टास्क वापस जाने के लिए

static Task ProcessId(int id) 
{ 
    // just process the id 
} 

का संसाधन आईडी इस

// This Gets all the ID(s)-IEnumerable <int> 
var clientIds = new Clients().GetAllClientIds(); 
// This gets all the tasks to be executed 
var tasks = clientIds.Select(id => ProcessId(id)). 
// this will create a task that will complete when all of the `Task` 
// objects in an enumerable collection have completed. 
await Task.WhenAll(tasks); 
+0

मैं तेज़ था: पी –

+1

@ पावेल ट्राका लेकिन एनकोसी ने आसान उपयोग किया। चयन करें (आईडी => प्रोसेस आईडी (है)): पी –

+0

हाँ, मैं अभी भी इस प्रतिनिधि दौड़ में बिल्कुल नया हूं। –

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