c# - 如何在 C# 中创建基于 DataTable.Rows.Count 的对象?

标签 c# multithreading linq datatable

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

而且我不知道为什么 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();
    }
}

最佳答案

And I don't know why OpenNRowsInData(user, pwd); always only get first rows.

我觉得你的第二个威胁太快了。在第一行完成之前,它将执行 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:

如果你想在两个浏览器中同时执行它,你可以创建一个例程来执行 AllCasethis 这两种情况,你可以在 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 并在那里使用它

关于c# - 如何在 C# 中创建基于 DataTable.Rows.Count 的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38821739/

相关文章:

c# - volatile IEnlistmentNotification 和 TransactionScope.AsyncFlowEnabled = true

c# - Entity Framework ,按日/周/月在日期时间工作

c - 为什么我的生产者 - 消费者模式有意外的输出?

java - Tomcat Java 错误

javascript - C# Linq SelectMany,TypeScript 等价物

c# - 将段落内的超链接绑定(bind)到命令 (MVVM)

c# - 有Point3D吗?

在不同的线程上创建一个计时器 - 没有回调函数(C,Windows)

c# - linq 中的分组和排序

c# - 为什么 distinct in LINQ 不适用于这种情况?