Reputation: 21
I'm trying to let my accounts do multiple logins with tasks. I am by no means an expert, I've only just started, but I'm stuck with the following problem I have.
For some reason the tasks keep looping, but they should not. I can't really figure out what the problem is, so I figured that someone on here might know the solution.
public async void Login()
{
for (int i = 0; i < objectsToCreate; i++)
{
try
{
this.Invoke((MethodInvoker)delegate()
{
MyEmail = listView1.Items[i].SubItems[0].Text;
MyPassword = listView1.Items[i].SubItems[1].Text;
MySecurity = listView1.Items[i].SubItems[2].Text;
});
var loginDetails = new LoginDetails(MyEmail, MyPassword, MySecurity, Platform.Ps3);
client[i] = new FutClient();
var loginResponse = await client[i].LoginAsync(loginDetails);
MessageBox.Show("Succesful login");
}
catch (Exception ex)
{
string foutMelding = ex.InnerException.ToString();
ListViewItem exception = new ListViewItem(time);
exception.SubItems.Add(foutMelding);
listView2.BeginInvoke(new MethodInvoker(() => listView2.Items.Add(exception)));
}
}
}
public void StartLogin()
{
Task[] tasks = new Task[objectsToCreate];
for (int i = 0; i < objectsToCreate; i++)
{
tasks[i] = new Task(() => Login());
}
foreach (Task task in tasks)
{
task.Start();
}
}
I call the StartLogin method with a button in my form. It then proceeds to login the accounts, but for some reason the tasks keep looping and I really can't figure out the reason, since I only just started with using Tasks. I would really appreciate it if someone could help me out.
Upvotes: 2
Views: 113
Reputation: 70671
Based on the code you posted, I would expect the logic in the loop inside the Login()
method to execute 16 times: 4 times for each time the Login()
method itself is called, due to the for (int i = 0; i < objectsToCreate; i++)
statement at the beginning of that method; and that, 4 times because you are creating 4 tasks to call the method.
It's hard to know what you meant to write, but I'm guessing you want to remove the loop from the Login()
method itself. It looks like an artifact left over from a previous implementation attempt.
As an aside: it is a little odd to be mixing invocation of an async
method with an explicit Task
invocation of that method. It seems to me you could accomplish much the same result by simply calling the Login()
method four times (minus the loop in the Login()
method, of course).
Here's how I'd write the code:
public async void Login()
{
try
{
MyEmail = listView1.Items[i].SubItems[0].Text;
MyPassword = listView1.Items[i].SubItems[1].Text;
MySecurity = listView1.Items[i].SubItems[2].Text;
var loginDetails = new LoginDetails(MyEmail, MyPassword, MySecurity, Platform.Ps3);
client[i] = new FutClient();
var loginResponse = await client[i].LoginAsync(loginDetails);
MessageBox.Show("Succesful login");
}
catch (Exception ex)
{
string foutMelding = ex.InnerException.ToString();
ListViewItem exception = new ListViewItem(time);
exception.SubItems.Add(foutMelding);
listView2.Items.Add(exception);
}
}
public void StartLogin()
{
for (int i = 0; i < objectsToCreate; i++)
{
var _ = Login();
}
}
Note that, in this approach, since the Login()
method is initially called from the UI thread (I presume...you didn't show the actual caller of the StartLogin()
method, you don't need to use Invoke()
or BeginInvoke()
when accessing UI elements in that method.
(The var _ =
is just to keep the compiler from complaining that I didn't await
the async
method. Here, that's on purpose :) ).
Upvotes: 1
Reputation: 218
It doesn't loop indefinitely - it executes exactly 16 times. This is because you essentially have a doubly nested for loop - one in your StartLogin method, and one in your Login method. Perhaps you aren't expecting the contents of your Login method to execute 4 times each time your Login method is called?
Upvotes: 1