【问题标题】:Thread sleep in a for loop线程在 for 循环中休眠
【发布时间】:2010-02-07 22:26:39
【问题描述】:

我需要您的帮助才能使用此方法:

for (int i =0; i<dt.count; i++)
{
    process...
    sleep(3000);
}

int sleeptime=0;
private void timer2_Tick(object sender, EventArgs e)
{
    for (int i = 0; i &#60; mylist.Items.Count;)
    {
        listBox1.Items.Add(mylist.Items[i].Name.ToString() + "starting...");
        sleeptime = int.Parse(mylist.Items[i++].TimeSpan.ToString()) - timer2.Interval;
        System.Threading.Thread.Sleep(sleeptime);
    }
    timer1.Start();
    timer2.Stop();
}

但我没有看到像瀑布一样的数据流。

【问题讨论】:

  • 您可以编辑您的问题吗?不清楚你在问什么。

标签: c# .net winforms multithreading


【解决方案1】:

您正在阻塞 UI 线程 - 在您离开事件处理程序之前,通常不会显示任何更新。一个 hacky 方法是使用 Application.DoEvents(),但这是懒惰的并且有重新进入的风险尤其是如果你正在暂停。

更好的方法是在后台线程上完成工作,并使用Invoke 将数据推送到 UI(不要从工作线程与 UI 对话)。

或者只是在单独的刻度中添加单个项目?

这是一个使用BackgroundWorker 工作的示例,使用ReportProgress 将项目推送到UI:

using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
static class Program
{
    static void Main()
    {
        // setup some form state
        Form form = new Form();
        ListView list = new ListView();
        list.View = View.List;
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        form.Controls.Add(list);
        list.Dock = DockStyle.Fill;
        // start the worker when the form loads
        form.Load += delegate {
            worker.RunWorkerAsync();
        };
        worker.DoWork += delegate
        {
            // this code happens on a background thread, so doesn't
            // block the UI while running - but shouldn't talk
            // directly to any controls
            for(int i = 0 ; i < 500 ; i++) {
                worker.ReportProgress(0, "Item " + i);
                Thread.Sleep(150);
            }
        };
        worker.ProgressChanged += delegate(object sender,
           ProgressChangedEventArgs args)
        {
            // this is invoked on the UI thread when we
            // call "ReportProgress" - allowing us to talk
            // to controls; we've passed the new info in
            // args.UserState
            list.Items.Add((string)args.UserState);
        };
        Application.Run(form);
    }
}

【讨论】:

    【解决方案2】:

    或者您可以使用 System.Threading.Timer 类。计时器的回调在 ThreadPool 的线程上执行,而不是 UI 线程。但是,您不能直接访问任何 GUI 控件,因此您必须使用 Invoke。

    【讨论】:

      猜你喜欢
      • 2011-04-26
      • 2014-10-26
      • 1970-01-01
      • 2021-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-22
      相关资源
      最近更新 更多