对于循环停止迭代列表框中的第一个项目之后

时间:2011-11-26 22:11:57

标签: c# multithreading for-loop iteration

我想要一个for循环(ListBox中的每个项目)来执行方法。

现在发生的事情是第一项正在被选中,方法正在执行,但是它没有选择第二项,它只是坐在那里。

你能帮忙吗?

这是for循环的外观:

for(int i = 0; i < listBox8.Items.Count; i++) {
    listBox8.SetSelected(i, true);
    listBox8.SelectedIndex = 0;

    Thread t = new Thread(signinmobile);
    t.Start();
    CheckForIllegalCrossThreadCalls = false;
}

这是我的潜艇:

public void signinmobile()
{
    string yourString = listBox8.SelectedItem.ToString();
    string[] strArray = yourString.Split(':');

    System.Net.ServicePointManager.Expect100Continue = false;
    string postData = "authenticity_token=401538d41ace8f334c3d&username=" + strArray[0] + "&password=" + strArray[1] + "";
    CookieContainer tempCookies = new CookieContainer();
    UTF8Encoding encoding = new UTF8Encoding();
    byte[] byteData = encoding.GetBytes(postData);

    HttpWebRequest postReq = (HttpWebRequest)WebRequest.Create("https://mobile.twitter.com/session");
    postReq.Method = "POST";
    postReq.KeepAlive = true;
    postReq.CookieContainer = tempCookies;
    postReq.ContentType = "application/x-www-form-urlencoded";
    postReq.Referer = "https://mobile.twitter.com/session";
    postReq.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)";
    postReq.ContentLength = byteData.Length;

    Stream postreqstream = postReq.GetRequestStream();
    postreqstream.Write(byteData, 0, byteData.Length);
    postreqstream.Close();
    HttpWebResponse postresponse = default(HttpWebResponse);

    postresponse = (HttpWebResponse)postReq.GetResponse();
    tempCookies.Add(postresponse.Cookies);
    StreamReader postreqreader = new StreamReader(postresponse.GetResponseStream());

    string accountstatus = postreqreader.ReadToEnd();

    webBrowser1.DocumentText = accountstatus;

    if (accountstatus.Contains("Sign in information is not correct"))
    {
        listBox9.Items.Add(listBox8.SelectedItem.ToString() + "\r");
        while (listBox8.SelectedItems.Count > 0)
        {
            listBox8.Items.Remove(listBox8.SelectedItems[0]);
        }
    }
    else
    {
        listBox2.Items.Add(listBox8.SelectedItem.ToString() + "\r");

        while (listBox8.SelectedItems.Count > 0)
        {
            listBox8.Items.Remove(listBox8.SelectedItems[0]);
        }
    }
}

4 个答案:

答案 0 :(得分:1)

您再次将所选索引设置为0.这是第一项。所以循环的每次迭代都停留在第一个项目上。

答案 1 :(得分:1)

您每次都会将SelectedIndex重置为0,因此它不会向前移动......只需删除该行。

答案 2 :(得分:1)

以下行始终为每个循环周期选择第一项

listBox8.SelectedIndex = 0;

我相信您可以删除此行,因为上一行(listBox8.SetSelected(i, true);)已经选择了

编辑:自问题更新

我觉得这里可能会发生异常。在try/catch(Exception ex)方法调用周围添加signinmobile块,并告诉我们是否处理了eny异常。

BTW,为什么你在另一个线程中运行方法?看起来有线程同步问题,所以如果列表包含多个线程将运行多个线程并删除列表中的项目,然后调用SetSelected失败,因为它缓存了当前不存在的索引值i一些线程已被删除项...所以在单线程中运行全部或在t.Join()之后执行t.Start()所以主线程将等待工作线程完成并继续下一个循环周期。

答案 3 :(得分:0)

以上答案很好地解决了listBox8.SelectedIndex = 0;问题。

我只是想对signinmobile方法发表评论。

大师,如果我错了,请纠正我但是如果这个方法使用列表框选择在创建的线程中做一些后台工作那么整个事情都行不通!当创建的线程旋转并开始处理所选项string yourString = listBox8.SelectedItem.ToString();时 父线程将更改for循环listBox8.SetSelected(i, true);中的选择,这可能会干扰先前创建的工作线程。 为了确保这是线程安全的,我将提取项目以在for循环上工作并将其作为字符串传递给工作线程。这样,您100%确定只有一个线程访问列表框并更改其选择。

建议修复

for(int i = 0; i < listBox8.Items.Count; i++) {
    Thread t = new Thread(new ParameterizedThreadStart(signinmobile));
    t.Start(listBox8.Items[i].ToString());
}
// Now that you started all thread to work on all items
// You can cleanup the list box safely

public void signinmobile(string parameter) {
    string yourString = parameter; // No need to access the shared list
    //...
    if (accountstatus.Contains("Sign in information is not correct")) {
       listBox9.Items.Add(parameter + "\r");
       // No need to access the shared list to remove the item
    } else  {
       listBox2.Items.Add(parameter + "\r");
       // No need to access the shared list to remove the item
    }
}
相关问题