[英]How to create n Object base on DataTable.Rows.Count in C#?
以下所有代碼僅用於創建兩個進程。 雖然我需要創建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()));
我想只獲得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();
}
}
我不知道為什么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
- 因為它們是連續的
編輯:
在編輯之后,當你第一次在位置0
OpenNRowsInData
中設置循環時,似乎就進入了循環
stepRun[idx] = 1;
然后再打電話
AllCase();
這次它會執行
case 1:
ClickBuy();
break;
在第二次迭代時,它將再次嘗試打開
switch (stepRun[idx])
但是這次它會在stepRun
0
位置找到1
。 對於所有人而言永遠不會回到調用OpenNRowsInData
的情況。 這就是你只獲得第一行的原因。
編輯2:
如果你想在兩個瀏覽器中同時執行它,你可以創建一個執行AllCase
的兩種情況的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
並在那里使用它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.