2016-08-08 52 views
3

以下所有代碼僅用於創建兩個進程。雖然我需要創建n個進程來打開Chrome瀏覽器,並根據dtUser.Rows.Count運行OpenNRowsInData(user, pwd),因爲這是動態的。如何在C#中的DataTable.Rows.Count中創建n個對象庫?

而且我不知道爲什麼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())); 

我想只列userpwd

用代碼試過,我試圖在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

您可以發佈'OpenNRowsInData()'的實現嗎? –

+0

你的問題是爲什麼'OpenNRowsInData(user,pwd);'總是隻得到第一行..?=!只是爲了澄清:在'dtUser.Rows'中你有7行,所以有7個用戶,你想登錄他們每個人。當你在'AllCase'中通過foreach循環時,它是否產生了正確的'user'和'pwd'值? –

+0

在第一次迭代後退出循環嗎?還是它給你7次同一行? –

回答

1

而且我不知道爲什麼OpenNRowsInData(用戶,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]) 

進行切換,但這次將在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並在那裏使用它

+0

和你的評論一樣,我希望兩個瀏覽器同時執行'AllCase()'函數。在C#中,當使用多個線程時,我通常會收到一個進程是成功的所有任務,其餘線程將失敗。那是第一個進程在其他線程可以試圖訪問這個之前編輯一個變量的值嗎? – vanloc

+0

實際上在你的情況下它確實如此。它會覆蓋'stepRun [idx] = 1;'。但你的平行方法並沒有解決這兩個瀏覽器,它解決了'AllCase'的兩種情況。 –

+0

你真棒。非常感謝@mongzhu。 – vanloc