user1017524
user1017524

Reputation: 241

For loop stops iterating after first item in listbox

I have a for loop that I want (for every item in a ListBox) to execute a method.

What happening now is the first item is being selected, the method is being executed, but then it doesn't select the second item, it just sits there.

Can you help?

This is how my for loop looks:

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

And here is my sub:

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

Upvotes: 1

Views: 1032

Answers (4)

GETah
GETah

Reputation: 21439

The above answers have well caught the listBox8.SelectedIndex = 0; issue.

I just want to comment on the signinmobile method.

Gurus, correct me if I am wrong but if this method is using the list box selection to do some background work in the created thread then the whole thing won't work! By the time the created thread spins and starts working on the selected item string yourString = listBox8.SelectedItem.ToString(); the parent thread will change the selection in the for loop listBox8.SetSelected(i, true); which might disturb the previously created worker thread. To make sure this is thread safe, I would extract the item to work on on the for loop and pass it as a string to the worker thread. This way you are 100% sure only one thread accesses the list box and changes its selection.

Suggested fix

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

Upvotes: 0

sll
sll

Reputation: 62544

Following line always selecting the first item for each loop cycle

listBox8.SelectedIndex = 0;

I believe you can remove this line at all because previous one (listBox8.SetSelected(i, true);) already does selection

EDIT: Since question was updated

I feel that here is exception may occur. Add try/catch(Exception ex) block around signinmobile method call and say us whether eny exception was handled.

BTW, Why you are running method in an other thread? Looks like there is thread sync issue so if list contains more then two items multiple threads would run and removing items in list, and then call to SetSelected fails since it cached index value i which currently not exists since some thread already removed item... So run all in single thread or do t.Join() after t.Start() so main thread would wait until working thread is done and them continue next loop cycle.

Upvotes: 1

Ry-
Ry-

Reputation: 225064

You're resetting SelectedIndex to 0 each time, so it follows that it won't move forward... just remove that line.

Upvotes: 1

SynerCoder
SynerCoder

Reputation: 12776

You set the selected index again to 0. That is the first item. So every iteration of the loop it stays at the first item.

Upvotes: 1

Related Questions