2016-08-08 44 views
3

Der gesamte Code unten nur zum Erstellen von zwei Prozessen. Während ich n Prozess erstellen muss, um den Chrome-Browser zu öffnen und OpenNRowsInData(user, pwd) basierend auf dtUser.Rows.Count auszuführen, weil dies dynamisch ist.Wie n Objektbasis auf DataTable.Rows.Count in C# erstellen?

Und ich weiß nicht warum OpenNRowsInData(user, pwd); immer nur die ersten Zeilen bekommen.

Ich habe einen DataTable Bereich von 1-7 Zeilen.

Normalerweise verwendete ich normalerweise, um zwei Objekte zu erstellen.

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(); 

In der Klasse 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; 
    } 
} 

Und in einem anderen, bevor ich parallel Prozess. Derzeit möchte ich es nicht verwenden.

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

Ich möchte nur Spalten user und pwd erhalten.

Mit Code versucht, ich habe versucht, einen Parameter in action() Methode wie: action(string user, string pwd) hinzuzufügen.

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); 
    } 
} 

Aktualisiert:

hinzufügen Klasse 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

könnten Sie die Implementierung von 'OpenNRowsInData()'? –

+0

Ihre Frage ist, warum 'OpenNRowsInData (user, pwd); 'immer nur die ersten Zeilen bekommt ..? =! Nur zur Verdeutlichung: In 'dtUser.Rows' haben Sie 7 Zeilen, also 7 Benutzer und Sie möchten sich anmelden. Wenn Sie in 'AllCase' die foreach-Schleife durchlaufen, ergeben sich die richtigen' user'- und 'pwd'-Werte? –

+0

beendet die Schleife nach der ersten Iteration? oder gibt es dir 7 mal die selbe Reihe? –

Antwort

1

Und ich weiß nicht, warum OpenNRowsInData (Benutzer, PWD); bekomme immer nur die ersten Reihen.

Es scheint für mich, dass Ihre zweite Bedrohung zu schnell ist. Bevor die erste abgeschlossen werden kann, wird ClickBuy(); ausgeführt, sodass nur die erste Zeile verarbeitet werden kann.

versuchen es einen Schritt nach dem anderen

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(); 
    } 
} 

zu tun, wenn Sie es für beide Browser tun wollen versuchen, eine Schleife auf dem Array ausgeführt wird:

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

Diese Parallelisierung Zeit tatsächlich zahlen würde aus.Weil Sie zugleich das gleiche Material in beiden Browsern tun könnten, aber es scheint, sollen Sie beide AllCase nicht tun - Fälle in den gleichen Browser zur gleichen Zeit, weil sie

EDIT aufeinander folgend sind:

nach dem bearbeiten scheint es, dass, wenn Sie in Ihrem Schleifen Sie das erste Mal los gehen in OpenNRowsInData an der Position 0

stepRun[idx] = 1; 

und dann wieder 0

nennen
AllCase(); 

diesmal wird es

case 1: 
     ClickBuy(); 
     break; 

auf der zweiten Iteration führen Sie es wieder auf

switch (stepRun[idx]) 

zu wechseln versuchen, aber dieses Mal wird es eine 1 auf der Position 0 in stepRun finden . Für alle und nie wieder in den Fall gehen, um OpenNRowsInData anrufen. Deshalb erhalten Sie nur die erste Zeile.

EDIT 2:

, wenn Sie es zur gleichen Zeit in beiden Browsern tun möchten, können Sie eine Routine, die die beiden Fälle von AllCase und diese Routine führt Sie in zwei separate Threads ausführen können :

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

und die Fäden wie folgt beginnen:

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

Sie könnten auch das gesamte Browser-Objekt an die Methode übergeben und weiterleiten an OpenNRowsInData und verwenden Sie es dort

+0

Wie Ihr Kommentar möchte ich, dass beide Browser gleichzeitig die Funktion 'AllCase()' ausführen. In C#, wenn ich mehrere Threads benutze, bekomme ich normalerweise einen Prozess, der alle Missionen erfolgreich ist und der verbleibende Thread wird fehlschlagen. Editiert der erste Prozess Werte einer Variablen, bevor ein anderer Thread versuchen kann, darauf zuzugreifen? – vanloc

+0

tatsächlich in Ihrem Fall tut es. es überschreibt die 'stepRun [idx] = 1;'. Aber Ihr paralleler Ansatz geht nicht an die zwei Browser heran, die die beiden Fälle 'AllCase' angehen. –

+0

Sie sind fantastisch. Vielen Dank @mongzhu. – vanloc