2012-07-18 48 views
0

這是一個簡單的.NET 4應用程序。這是我要運行的代碼:在.NET 4中異步運行方法的簡單方法是什麼?

string username = "userfoo"; 
string password = "passwordfoo"; 

for (int i = 0; i < 2000; i++) 
{  
    uint matchId; 
    if (!uint.TryParse(i.ToString(), out matchId)) 
    { 
     Console.WriteLine("Invalid Match ID!"); 
     return; 
    } 

    Client client = new Client (username, password, matchId); 

    // connect 
    client.Connect(); 

    client.Wait(); 

    if (client.Match != null) 
    { 
     Console.WriteLine("Inserting match: #{0}", client.Match.match_id); 
     Helpers.MatchHelper.AddMatchToDatabase(client.Match); 
    } 
    else 
    { 
     Console.WriteLine("Couldn't get match: #{0}", 1); 
    } 

}

而不是做這一個接一個(它會永遠需要 - 根據我的計算415天不停),什麼是調用的每次迭代的最簡單方法這是for循環異步?

大多數問題和文章都很舊(大約在2001年!)肯定必須有更現代化的方法嗎?

http://msdn.microsoft.com/en-us/magazine/cc301332.aspx

+0

你有沒有考慮過使用任務? – 2012-07-18 17:51:32

回答

2

你可以在這裏找到的信息:http://msdn.microsoft.com/en-us/library/ff963552.aspx。基本上,你只需使用Parallel.For(0, n, x => doSomething)。這需要並行化。這是PLINQ的一項功能,非常易於使用,在我的經驗中效果很好。

你的樣品是這樣的:

string username = "userfoo"; 
string password = "passwordfoo"; 

Parallel.For(0, 2000, i => 
{  
    uint matchId; 
    if (!uint.TryParse(i.ToString(), out matchId)) 
    { 
     Console.WriteLine("Invalid Match ID!"); 
     return; 
    } 

    Client client = new Client (username, password, matchId); 

    // connect 
    client.Connect(); 

    client.Wait(); 

    if (client.Match != null) 
    { 
     Console.WriteLine("Inserting match: #{0}", client.Match.match_id); 
     Helpers.MatchHelper.AddMatchToDatabase(client.Match); 
    } 
    else 
    { 
     Console.WriteLine("Couldn't get match: #{0}", 1); 
    } 
}); 
+0

是的,我最初的測試中有類似的結果。我很好奇:因爲這使用互聯網來獲取數據,所以一次打開2000個連接來下載信息根本沒有任何下載。有沒有辦法限制*一次啓動的任務數量?就像說,在任何時候執行40次? – 2012-07-18 17:59:47

+0

據我的理解,這不是它的工作原理。它根據您的機器的能力打開「適當」的線程數量。但我不知道有什麼方法可以讓你明確定義並行性級別。 – 2012-07-18 18:02:23

+0

關於如何解決這個問題的任何建議? – 2012-07-18 18:06:20

1

如果我理解正確的話,你要在一個單獨的線程中運行這些。下面是做到這一點的一種方法: 您需要從循環的代碼進入一個void函數:

void MyThreadInsteadOfLoop(object parameter) 
{ 
int i = (int)parameter; 
uint matchId; 
if (!uint.TryParse(i.ToString(), out matchId)) 
{ 
    Console.WriteLine("Invalid Match ID!"); 
    return; 
} 

Client client = new Client (username, password, matchId); 

// connect 
client.Connect(); 

client.Wait(); 

if (client.Match != null) 
{ 
    Console.WriteLine("Inserting match: #{0}", client.Match.match_id); 
    Helpers.MatchHelper.AddMatchToDatabase(client.Match); 
} 
else 
{ 
    Console.WriteLine("Couldn't get match: #{0}", 1); 
} 
} 

在你的主線程,你需要準備線程運行,啓動它們,並等待他們完成, 如果你想。下面的代碼:

//Create threads 
List<Thread> threads = new List<Thread>(); 
for(int i=0;i<2000;i++) 
{ 
    threads.Add(new Thread(new ParameterizedThreadStart(MyThreadInsteadOfLoop))); 
} 
//Start threads 
int x = 0; 
foreach(var t in threads) 
{ 
    t.Start(x); 
    x++; 
} 
//wait for the threads to finish 
foreach(var t in threads) 
{ 
    t.Join(); 
} 

要知道,你必須做出MatchHelper類,並與你的線程線程安全的交換數據的其他類,並傾向於大量開銷添加到您的程序。另外,您可能會遇到網絡連接問題。 只有[NumberOfCpuCores] * 2線程會一次有效地工作(* 2,因爲超線程),但是因爲您必須等待客戶端(我真的希望這不是一段時間(真正的)週期隱身)可能會得到至少部分隱藏。

相關問題