2012-07-18 44 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,因为超线程),但是因为您必须等待客户端(我真的希望这不是一段时间(真正的)周期隐身)可能会得到至少部分隐藏。

相关问题