2015-02-06 8 views
5

मैं सरल कोड निम्नलिखित है:सी # में मार डाला कार्यों के आँकड़ों जाओ

var tasks = statements.Select(statement => _session.ExecuteAsync(statement)); 
var result = Task.WhenAll(tasks).Result; 
[...] 

मैं मिनट, अधिकतम की गणना कैसे कर सकते हैं, औसत, आदि सभी निष्पादित कार्यों की? कार्य वर्ग में "निष्पादित मिलिसेकंड" जैसी संपत्ति नहीं है

+2

यह कार्य का कार्य नहीं है। स्टॉपवॉच का उपयोग करने के लिए आपको क्या रोकता है, जैसा कि [मेरे कोड को कितना समय लगता है?] (Http://stackoverflow.com/questions/1285052/how-long-does-my-code-take-to-run) – CodeCaster

+0

मैंने स्टॉपवॉच का उपयोग करने की कोशिश की, लेकिन मुझे नहीं पता कि मैं प्रत्येक कार्य को कैसे माप सकता हूं। –

+1

तो आप _each_ कार्य को मापना चाहते हैं, _all_ कार्यों नहीं? फिर आपको प्रत्येक कार्य में स्टॉपवॉच लागू करना होगा। – CodeCaster

उत्तर

3
निम्न एक्सटेंशन विधि के साथ

:

public static class EnumerableExtensions 
{ 
    public static IEnumerable<Task<TimedResult<TReturn>>> TimedSelect<TSource, TReturn>(
     this IEnumerable<TSource> source, 
     Func<TSource, Task<TReturn>> func) 
    { 
     if (source == null) throw new ArgumentNullException("source"); 
     if (func == null) throw new ArgumentNullException("func"); 

     return source.Select(x => 
     { 
      Stopwatch stopwatch = new Stopwatch(); 
      stopwatch.Start(); 

      Task<TReturn> task = func(x); 

      Task<TimedResult<TReturn>> timedResultTask = task 
       .ContinueWith(y => 
       { 
        stopwatch.Stop(); 

        return new TimedResult<TReturn>(task, stopwatch.Elapsed); 
       }); 

      return timedResultTask; 
     }); 
    } 
} 

public class TimedResult<T> 
{ 
    internal TimedResult(Task<T> task, TimeSpan duration) 
    { 
     Task = task; 
     Duration = duration; 
    } 

    public readonly Task<T> Task; 
    public readonly TimeSpan Duration; 
} 

और callsite

var tasks = statements.TimedSelect(statement => _session.ExecuteAsync(statement)); 

var result = Task.WhenAll(tasks).Result; 

आप परिणाम है कि आप की आवश्यकता होगी

// Whatever works (ugly, but just as an example)... 
var min = result.Select(x => x.Duration).Min(); 
var max = result.Select(x => x.Duration).Max(); 
var avg = new TimeSpan((long)result.Select(x => x.Duration.Ticks).Average()); 

नोट निकाल सकते हैं कि इस पूल इंतज़ार कर समय भी शामिल है (एक कार्य धागा उपलब्ध होने के लिए समय इंतजार कर रहा है), और इसके लिए सटीक नहीं हो सकता है।

इस विस्तार का एक गैर-सामान्य संस्करण पाठक के लिए एक अभ्यास है।

+0

'Timed' विधि के साथ आपका पिछला संस्करण बेहतर था, क्योंकि यह' _session की अनुमति देता है।ExecuteAsync (कथन) 'सरणी' कथन ' –

+0

में तत्वों के प्रकार का नहीं है यदि आप' सार्वजनिक स्थैतिक IENumerable <कार्य >> timedSelect (यह IENumerable स्रोत, Func > func) के लिए फ़ंक्शन परिभाषा में पंक्ति बदलता है। यह बेहतर होगा –

+0

मुझे 'TimedSelect' बेहतर मिला, क्योंकि स्टॉपवॉच कार्य की शुरुआत से पहले शुरू होता है। कार्य के बाद 'टाइमेड चेन' के साथ एक शुरू किया गया था और गलत समय हो सकता है।/संपादित करें: अद्यतन, धन्यवाद। – Caramiriel

2

आप कार्यों को ContinuationTask दे सकते हैं, जो कार्य पूरा होने के बाद कहा जाता है। इसके साथ आप स्टॉपवॉच का एक समूह का उपयोग कर सकते हैं और निरंतर कार्य को अलग-अलग रोकने के लिए उपयोग कर सकते हैं।

+0

मैं बेस टास्क और ContinuationTask में स्टॉपवॉच कैसे साझा कर सकता हूं। –

+0

क्या आप कोड उदाहरण दिखा सकते हैं? –

+0

कार्यों को बदलने से बचने के लिए, मेरे पास स्टॉपवॉच होगा [], उन्हें सभी को बंद कर दें और फिर nth कार्य में nth stopwatch को रोक दें। तथापि। SInce टास्क। WaitAll() आपके कार्यों को "निष्पक्ष" तरीके से शुरू करने के बारे में कोई गारंटी नहीं देता है, ये मेट्रिक्स आपको बताएंगे कि जब कार्य निष्पादित करने में कितना समय लगेगा, तो कड़ाई से बोलने के बजाय कार्य समाप्त हो गए थे। एक सामान्य बिंदु निष्पादन धागे एक साझा संसाधन होते हैं, इसलिए आप समसामयिक रूप से चीजों को रेस नहीं कर सकते .. –

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