2014-02-27 100 views
1

我想要做的是排隊一個類似的任務大列表。每項任務完成的時間很短,但其中有很多。對於列表中的每個項目,我創建一個委託並調用delegate.BeginInvoke方法,然後移動到創建下一個項目。爲什麼回調/ endinvoke在所有調用被調用後都會發生?

我希望在下面的例子中,我會得到至少一個「* ** * **末尾調用* ***」發生所有的開始調用被調用。相反,它看起來好像編譯器在收到任何結束調用之前就開始了所有的開始調用。

這是正常的行爲嗎?是否有另一種方法可以在另一個線程上發送任務/方法,並在繼續激發更多任務的同時接收它?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Threading; 

namespace AsyncResultTesting 
{ 
    class Program 
    { 

     static void Main(string[] args) 
     { 
      Console.WriteLine("Starting"); 
      for (int i = 0; i < 100; i++) 
      { 
       delMeth d = new delMeth(sleepMethod); 
       Console.WriteLine(string.Format("Calling the begin invoke from thread: {0} for ID: {1}", Thread.CurrentThread.ManagedThreadId.ToString(), i.ToString())); 
       IAsyncResult ar = d.BeginInvoke(i, callbackMessage, d); 
      } 
      Console.ReadLine(); 
     } 

     private delegate int delMeth(int id); 

     private static int sleepMethod(int id) 
     { 
      Console.WriteLine(Environment.NewLine + String.Format("Thread: {0} is sleeping. Delegate id is {1}", Thread.CurrentThread.ManagedThreadId.ToString(),id.ToString())); 
      Console.WriteLine(String.Format("Thread Properties IsThreadPoolThread? = {0} isThreadBackground? = {1} ThreadState: = {2}", Thread.CurrentThread.IsThreadPoolThread.ToString(), Thread.CurrentThread.IsBackground.ToString(), Thread.CurrentThread.ThreadState.ToString())); 
      Console.WriteLine(""); 
      Thread.Sleep(100);    
      return id; 

     } 

     private static void callbackMessage(IAsyncResult ar) 
     { 
      delMeth d = (delMeth)ar.AsyncState; 
      int result = d.EndInvoke(ar); 
      Console.WriteLine(Environment.NewLine + "************************ END INVOKE *****************************"); 
      Console.WriteLine(String.Format("Delegate was just called back for id: {0}", result.ToString())); 
     } 

    } 


} 

不幸的是,我不得不使用.NET 3.5來設計它,所以我不能使用任何異步處理。

+4

你在睡覺100ms。這可能比開始執行100個任務的時間要長得多。這裏意外的是什麼? – usr

回答

1

USR是正確的。一切都在運作,我期望它。如果我睡了10毫秒,然後我看到EndInvokes在BeginInvokes中間回來。

謝謝USR。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Threading; 

namespace AsyncResultTesting 
{ 
    class Program 
    { 

     static void Main(string[] args) 
     { 
      Console.WriteLine("Starting"); 



      for (int i = 0; i < 150; i++)   { 
       delMeth d = new delMeth(sleepMethod); 
       Console.WriteLine(string.Format("Calling the begin invoke from thread: {0} for ID: {1}", Thread.CurrentThread.ManagedThreadId.ToString(), i.ToString())); 
       IAsyncResult ar = d.BeginInvoke(i, new AsyncCallback(callbackMessage), d); 
      } 
      Console.ReadLine(); 
     } 

     private delegate int delMeth(int id); 

     private static int sleepMethod(int id) 
     { 
      Console.WriteLine(Environment.NewLine + String.Format("Thread: {0} is sleeping. Delegate id is {1}", Thread.CurrentThread.ManagedThreadId.ToString(),id.ToString())); 
      Console.WriteLine(String.Format("Thread Properties IsThreadPoolThread? = {0} isThreadBackground? = {1} ThreadState: = {2}", Thread.CurrentThread.IsThreadPoolThread.ToString(), Thread.CurrentThread.IsBackground.ToString(), Thread.CurrentThread.ThreadState.ToString())); 
      Console.WriteLine(""); 
      Thread.Sleep(10);    
      return id; 

     } 

     private static void callbackMessage(IAsyncResult ar) 
     { 
      delMeth d = (delMeth)ar.AsyncState; 
      int result = d.EndInvoke(ar); 
      Console.WriteLine(Environment.NewLine + "************************ END INVOKE *****************************"); 
      Console.WriteLine(String.Format("Delegate was just called back for id: {0}", result.ToString())); 
     } 

    } 


} 
相關問題