以下所有代码仅用于创建两个进程。虽然我需要创建n流程来打开Chrome浏览器并根据OpenNRowsInData(user, pwd)
运行dtUser.Rows.Count
,因为这是动态的。
我不知道为什么OpenNRowsInData(user, pwd);
总是只获得第一行。
我的DataTable
范围是1-7行。
通常,我通常用来创建两个对象。
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()));
我想只获得user
列和pwd
。
尝试使用代码,我尝试在action()
方法中添加参数,例如:action(string user, string pwd)
。
public static void ForEach<T>(this IEnumerable<T> source, Action<T> 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();
}
}
答案 0 :(得分:1)
我不知道为什么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();
}
}
如果您想为两个浏览器执行此操作,请尝试在阵列上运行循环:
for(int j = 0; j < browser.Length;j++)
{
AllCase(0, j);
AllCase(1, j);
}
这次并行化实际上会得到回报。因为您可以同时在两个浏览器中执行相同的操作,但似乎您不应同时执行两个AllCase
- 相同浏览器中的情况,因为它们是连续的
修改强>
编辑完成后,当您第一次在OpenNRowsInData
位置0
stepRun[idx] = 1;
然后再次致电
AllCase();
这次它将执行
case 1:
ClickBuy();
break;
在第二次迭代时,它将再次尝试打开
switch (stepRun[idx])
但这次会在1
的{{1}}位置找到0
。对全部
并且永远不会回到案件中致电stepRun
。
这就是你只获得第一行的原因。
编辑2:
如果您想在两个浏览器中同时执行此操作,您可以创建执行OpenNRowsInData
和此例程的两种情况的例程,您可以在2个单独的线程中运行:
AllCase
并启动这样的线程:
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();
}
并在那里使用