如何在C#中的DataTable.Rows.Count上创建n对象?

以下所有代码仅用于创建两个进程。 虽然我需要创建n进程来打开Chrome浏览器并基于dtUser.Rows.Count运行OpenNRowsInData(user, pwd) ,因为这是动态的。

我不知道为什么OpenNRowsInData(user, pwd); 总是只获得第一行。

我有一个1-7行的DataTable范围。

通常,我通常用来创建两个对象。

 static myObject[] browser = new myObject[] { new myObject(Browsers.Chrome, 0), new myObject(Browsers.Chrome, 0) }; Thread t1, t2; t1 = new Thread(new ThreadStart(AllCase)) { Name = "Thread1" }; t1.Start(); t2 = new Thread(new ThreadStart(AllCase)) { Name = "Thread2" }; t2.Start(); 

AllCase类中:

 static int[] stepRun = { 0, 0 }; private void AllCase() { int idx = int.Parse(Thread.CurrentThread.Name.Replace("Thread", "")) - 1; switch (stepRun[idx]) { case 0: foreach (DataRow row in dtUser.Rows) { user = row["user"].ToString(); pwd = row["pwd"].ToString(); OpenNRowsInData(user, pwd); } break; case 1: ClickBuy(); break; } } 

另一方面,在我使用并行进程之前。 目前,我不想使用它。

 Parallel.ForEach( dtUser.AsEnumerable(), items => OpenNRowsInData(items["user"].ToString(), items["pwd"].ToString())); 

我想只获得userpwd列。

尝试使用代码,我尝试在action()方法中添加一个参数,如: action(string user, string pwd)

 public static void ForEach(this IEnumerable source, Action action) { if (source == null) throw new ArgumentNullException("source"); if (action == null) throw new ArgumentNullException("action"); foreach (T item in source) { action(item); } } 

更新:

添加类OpenNRowsInData(string username, string password)

 private void OpenNRowsInData(string username, string password) { int idx = int.Parse(Thread.CurrentThread.Name.Replace("Thread", "")) - 1; try { browser[idx].DeleteAllCookies(); browser[idx].GoToUrl(link); browser[idx].waittingID("txtUserName", 15); browser[idx].FindElementById("txtUserName").SendKeys(username); browser[idx].FindElementById("txtpassword").SendKeys(password); browser[idx].FindElementById("btnlogin").Click(); stepRun[idx] = 1; AllCase(); } } 

我不知道为什么OpenNRowsInData(user,pwd); 总是只获得第一行。

对我来说,你的第二个威胁太快了。 在第一个完成之前它将执行ClickBuy(); 所以只能处理第一行。

尝试一步一步地做到这一点

 AllCase(0, 0); AllCase(1, 0); private void AllCase(int case, int browserNr) { switch (case) { case 0: foreach (DataRow row in dtUser.Rows) { user = row["user"].ToString(); pwd = row["pwd"].ToString(); OpenNRowsInData(user, pwd, browserNr); } break; case 1: ClickBuy(); break; } } private void OpenNRowsInData(string username, string password, int browserNr) { try { browser[browserNr].DeleteAllCookies(); browser[browserNr].GoToUrl(link); browser[browserNr].waittingID("txtUserName", 15); browser[browserNr].FindElementById("txtUserName").SendKeys(username); browser[browserNr].FindElementById("txtpassword").SendKeys(password); browser[browserNr].FindElementById("btnlogin").Click(); } } 

如果您想为两个浏览器执行此操作,请尝试在arrays上运行循环:

 for(int j = 0; j < browser.Length;j++) { AllCase(0, j); AllCase(1, j); } 

这次并行化实际上会得到回报。 因为你可以同时在两个浏览器中做同样的事情,但似乎你不应该同时在同一个浏览器中同时做两个AllCase - 因为它们是连续的

编辑:

编辑之后,当你第一次在位置0 OpenNRowsInData中设置循环时,似乎就进入了循环

 stepRun[idx] = 1; 

然后再打电话

 AllCase(); 

这次它会执行

  case 1: ClickBuy(); break; 

在第二次迭代时,它将再次尝试打开

 switch (stepRun[idx]) 

但是这次它会在stepRun 0位置找到1 。 对于所有人而言永远不会回到调用OpenNRowsInData的情况。 这就是你只获得第一行的原因。

编辑2:

如果你想在两个浏览器中同时执行它,你可以创建一个例程来执行AllCase的两种情况, 这个例程你可以在2个独立的线程中运行:

 public void doEverything(int browserIndex) { AllCase(0, browserIndex); AllCase(1, browserIndex); } 

并启动这样的线程:

 for(int j = 0; j < browser.Length;j++) { int brInd = j; Thread t= new Thread(()=>doEverything(brInd)); t.Start(); } 

您还可以将整个浏览器对象传递给该方法,并将其进一步传递给OpenNRowsInData并在那里使用它