2012-11-01 15 views
6

मोनो और MonoTouch के तहत के तहत, मैं जब मैं फोन के बीच एक लगभग 500 मिलीसेकंड देरी देख रहा हूँ:Task.Factory.StartNew() देरी मोनो/MonoTouch

StartNew(Action<object> action, object state, CancellationToken cancellationToken, 
    TaskCreationOptions creationOptions, TaskScheduler scheduler); 

और क्रियान्वित जब कार्यकर्ता कोड वास्तव में शुरू होता है। मैक पर मोनो के तहत

public static class TestTaskFactory 
{ 
    private class TaskInfo 
    { 
     public int Number; 
    } 

    private static int NUM_TASKS = 5; 
    private static int NumFinished = 0; 

    public static void Run() 
    { 
     for (int n = 1; n <= NUM_TASKS; n++) 
     { 
      Log("Starting task #" + n + " ..."); 
      var task_info = new TaskInfo { Number = n }; 
      var task = Task.Factory.StartNew(Worker, task_info, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); 
      Thread.Sleep(0); 
     } 

     Log("Waiting for tasks to finish ..."); 
     while (NumFinished < NUM_TASKS) 
     { 
      Thread.Sleep(1); 
     } 

     Log("All done"); 
    } 

    private static void Worker(object state) 
    { 
     var task_info = (TaskInfo)state; 
     Log("Task #" + task_info.Number + " running"); 

     // Do something 
     Thread.Sleep(2000); 

     // Done 
     ++NumFinished; 
    } 

    private static void Log(string msg) 
    { 
     Console.WriteLine(DateTime.Now.ToString("HH.mm.ss.fff") + ": Thread " + Thread.CurrentThread.ManagedThreadId + ": " + msg); 
    } 
} 

आउटपुट::

मैं इस को दिखाने के लिए एक परीक्षण बनाया

16.57.31.420: Thread 1: Starting task #1 ... 
16.57.31.508: Thread 1: Starting task #2 ... 
16.57.31.508: Thread 1: Starting task #3 ... 
16.57.31.508: Thread 1: Starting task #4 ... 
16.57.31.508: Thread 1: Starting task #5 ... 
16.57.31.508: Thread 1: Waiting for tasks to finish ... 
16.57.31.510: Thread 5: Task #1 running 
16.57.32.009: Thread 6: Task #2 running <-- Approx 500 msec later 
16.57.32.511: Thread 7: Task #3 running <-- Approx 500 msec later 
16.57.33.012: Thread 8: Task #4 running <-- Approx 500 msec later 
16.57.33.513: Thread 9: Task #5 running <-- Approx 500 msec later 
16.57.35.515: Thread 1: All done 

यह है के रूप में यदि मोनो से पहले एक मौजूदा धागा पुन: उपयोग करने 500 msec तक प्रतीक्षा करना चाहता है एक नया स्पॉइंग। यदि मैं 500 एमसीसी से कम कार्यकर्ता का समय कम करता हूं, तो देरी घट जाती है। उदाहरण के लिए, Thread.Sleep के कार्यकर्ता Thread.Sleep (2000) (50) को बदलने:

... 
17.13.20.262: Thread 5: Task #1 running 
17.13.20.314: Thread 5: Task #2 running <-- approx 50 msec later 
17.13.20.365: Thread 5: Task #3 running <-- approx 50 msec later 
17.13.20.416: Thread 5: Task #4 running <-- approx 50 msec later 
17.13.20.466: Thread 5: Task #5 running <-- approx 50 msec later 

लेकिन एमएस फ्रेमवर्क 4.0 के तहत, कोई बड़े कार्यकर्ता कोड से पहले देरी से शुरू होता है:

... 
17.05.42.238: Thread 9: Waiting for tasks to finish ... 
17.05.42.256: Thread 11: Task #1 running 
17.05.42.256: Thread 12: Task #3 running <-- little delay 
17.05.42.256: Thread 13: Task #4 running <-- little delay 
17.05.42.257: Thread 10: Task #2 running <-- little delay 
17.05.43.264: Thread 14: Task #5 running <-- little delay 

मोनो पर एक बग रिपोर्ट जमा करने से पहले, मैं सैनिटी जांचना चाहता था कि मुझे कुछ चिमटा नहीं मिल रहा है, मुझे मोनो बनाने या कार्य का उपयोग करने की आवश्यकता है। फैक्ट्री गलत। मैं वास्तव में अपने असली ऐप में अधिकतम समवर्ती शेड्यूलर का उपयोग कर रहा हूं।

तो मेरा प्रश्न: क्या यह मोनो/मोनो टच में एक बग है?

अपडेट: मैंने मोनो * के तहत थ्रेडपूल का उपयोग करके अमी बार के स्मार्ट थ्रेड पूल (github; Code Project article) पर स्विच किया है। जीएसरजो का Extended Thread Pool भी अच्छा लग रहा था, लेकिन बहुत निर्भरताएं थीं कि मैं मोबाइल पर बचने की कोशिश कर रहा था। मैंने Xamarim thread पर अपने कुछ सरल परीक्षण लिखे। मुझे शायद 100 अन्य थ्रेड पूल कार्यान्वयन याद आए, लेकिन मैं अभी तक SmartThreadPool से खुश हूं। मोनो टच के तहत संकलित करने के लिए WINDOWS_PHONE मोड का उपयोग करें।

उत्तर

6

तो मेरा प्रश्न: क्या यह मोनो/मोनो टच में एक बग है?

नहीं

जरूरी। मुझे संदेह है कि यह सिर्फ थ्रेड पूल हर 500ms से अधिक नए धागे को शुरू करने के इच्छुक नहीं है। ध्यान दें कि आप पहले कार्य को बहुत तेज़ी से शुरू कर रहे हैं। इसके बाद ही आप देरी देख रहे हैं।

यदि आप .NET 4.5 पर अधिक कार्यों का उपयोग करते हैं, तो आप प्रत्येक सेकेंड से शुरू होने वाले धागे के "भाग" को छोड़कर कुछ समान दिखाई देंगे।

आपको लगता है कि ThreadPool.SetMinThreads पर कॉल करने से यह पता चलता है कि यह मोनो टच में उपलब्ध है।

+0

हां, SetMinThreads() ने चाल की है। 500 एमसीईसी मूल्य बहुत मनमाना लगता है। यह आईओएस के तहत भी एक बहुत लंबा समय है मैक के लिए अकेले मोनो जहां मैं इसे भी देखता हूं। त्वरित googling के आधार पर यह एमएस फ्रेमवर्क के एक निश्चित संस्करण से स्थिर हो सकता है। मैं अधिक शोध/प्रयोग करेंगे और रिपोर्ट करूंगा। मोनो डिफ़ॉल्ट मुझे सही महसूस नहीं करते हैं। – t9mike

+0

@ t9mike: हाँ, मुझे लगता है कि .NET 4 से पहले समय था, जहां धागा पूल पूरी तरह से पूरी तरह से लिखा गया था, मुझे विश्वास है। –

+4

थ्रेडपूल में धागे की धीमी शुरुआत थ्रेड तूफान से बचने के लिए है। –

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