如何异步循环?

时间:2014-01-12 02:55:23

标签: c# winforms loops

我得到List个网站,我需要循环并花费在每一定时间内。循环需要是异步的,因为在每个网站上都会播放音乐,这是主要的一点 - 在这段时间内听到音乐,然后加载另一个页面并听取它的音乐等等。此外,表单需要可供用户操作。

我到目前为止的代码是:

public void playSound(List<String> websites)
{
    webBrowser.Navigate(Uri.EscapeDataString(websites[0]));

    foreach (String website in websites.Skip(1))
    {
        StartAsyncTimedWork(website);
        // problem when calling more times
    }

}

private System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();

private void StartAsyncTimedWork(String website)
{
    myTimer.Interval = 7000;
    myTimer.Tick += new EventHandler(myTimer_Tick);
    myTimer.Start();
}

private void myTimer_Tick(object sender, EventArgs e)
{
    if (this.InvokeRequired)
    {
        this.BeginInvoke(new EventHandler(myTimer_Tick), sender, e);
    }
    else
    {
        lock (myTimer)
        {
            if (this.myTimer.Enabled)
            {

                this.myTimer.Stop();
                // here I should get my website which I need to search
                // don't know how to pass that argument from StartAsyncTimedWork


            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

执行此操作的一种方法如下。

  • 使websites成为一个类字段(如果它还没有),因此计时器事件处理程序可以访问此集合。
  • 添加字段以跟踪当前索引。
  • 添加字段以防止重新调用PlaySounds
  • 您使用的是WinForms计时器,它在与表单相同的线程上执行,因此不需要InvokeRequired等。

一些伪代码(警告,这是未经测试的):

private bool isPlayingSounds;
private int index;
private List<String> websites;
private Timer myTimer;

private void Form1_Load()
{
    myTimer = new System.Windows.Forms.Timer();
    myTimer.Interval = 7000;
    myTimer.Tick += new EventHandler(myTimer_Tick);
}

public void PlaySounds(List<String> websites)
{
    if (isPlayingSounds)
    {
        // Already playing.
        // Throw exception here, or stop and play new website collection. 
    }
    else
    {
        isPlayingSounds = true;
        this.websites = websites;
        PlayNextSound();
    }
} 

private void PlayNextSound()
{
    if (index < websites.Count)
    {
        webBrowser.Navigate(Uri.EscapeDataString(websites[index]));
        myTimer.Start();

        // Prepare for next website, if any. 
        index++;
    }
    else
    {
        // Remove reference to object supplied by caller
        websites = null;

        / Reset index for next call to PlaySounds.
        index = 0;

        // Reset flag to indicate not playing. 
        isPlayingSounds = false;
    }
}

private void myTimer_Tick(object sender, EventArgs e)
{
    myTimer.Stop();
    PlayNextSound();
}