qasimalbaqali
qasimalbaqali

Reputation: 2131

foreach async sleep method

I am trying to make my foreach loop asynchronous. The loop loops the first time, does something then it will wait 40 seconds and then the loop loops again does something, waits 40 seconds etc...

In my situation I am looping around tweets, getting the tweet user name and then sending a tweet to them. I tried using the Thread.Sleep(40000) method but that just freezes the app and I can't use it, and the loop doesn't stop for 40 seconds and then loops again. The app freezes but the loop doesn't, the tweets are getting sent without even waiting at all. This how my code looks like

private void tweetButton_Click(object sender, EventArgs e)
{
            var tweets= .........
            foreach (var tweet in tweets)
            {
                // Do Something
                System.Threading.Thread.Sleep(40000);

 }

How would I let the foreach loop to pause before looping again on its self, and how would I make it pause without freezing my application?

Upvotes: 2

Views: 3663

Answers (3)

jtabuloc
jtabuloc

Reputation: 2535

You could implement background process in form. That would works in your case.

Upvotes: 0

Rob P.
Rob P.

Reputation: 15071

https://msdn.microsoft.com/en-us/library/hh194873(v=vs.110).aspx

I think you can await Task.Delay(40000); - to me that would be an 'async sleep' like you've asked for.

Alternatively, you could kick off a timer. The timer is probably a better choice, but will run on a threadpool thread.

EDIT: Not sure why this got -1...but if anyone has an explanation, I'd be interested.

I've verified that 'await Task.Delay(xyz)' does work for this purpose. Naturally, you'd need the async keyword to be added.

static async void DoSomething()
{
    for(var i = 0;i<25;i++)
    {
        // Do Something
        await Task.Delay(1000);
        Console.WriteLine("Sending a Tweet");
    }
}

I can't speak to the performance, but it seems to work fine for me.

Upvotes: 5

srandppl
srandppl

Reputation: 571

You want your code to run on a different thread, so it doens note impede the code running in your winforms gui thread. The best way for you specific needs is a timer that you kickoff once and that then does your job.

    {
        Timer t = new Timer();
        t.Interval = 50000;
        t.Elapsed += T_Elapsed;
        t.Start();            
    }

    private static void T_Elapsed(object sender, ElapsedEventArgs e)
    {

    }

If you need to access your winforms controls from here, you can use invoke, so the commands are placed into the the gui threads message loop.

control.Invoke((MethodInvoker)(() => 
{
    //Do your thing
}));

Upvotes: 4

Related Questions