【问题标题】:C#| Program does nothing after thread executedC#|线程执行后程序什么也不做
【发布时间】:2011-10-10 19:06:18
【问题描述】:

我的线程应该返回一个数组列表并将其放入文件中。
我的问题是它会停止(至少我是这么看的)。
线程:

 ArrayList files = new ArrayList();
            Thread getF = new Thread(delegate()
            {
                files = GetFiles(path);
            });
            getF.Start();
            if (getF.ThreadState == ThreadState.Stopped)
            {
                MessageBox.Show(files.Count.ToString());
                foreach (string file in files)
                {
                    if (file != "")
                    {...

获取文件:

ArrayList results = new ArrayList();
            try
            {
             *loops**code*...
            results.Add(srl);//add file to arrFiles
            *end loops*

                MessageBox.Show("Complete");
                return results;
            }

程序只是给了我 MessageBox.Show("Complete") 然后什么也不做。 提前致谢。

【问题讨论】:

  • 您遗漏了示例中最重要的部分——循环中的内容是什么?
  • 对于初学者,您希望 (1) 在您启动 getF 之后进行某种等待/循环构造,以确保线程在您尝试对 ArrayList 执行某些操作之前实际完成,并且/ 或 (2) 锁定 files 以防止您的代码同时尝试读取和写入它。

标签: c# multithreading thread-safety arraylist


【解决方案1】:
        getF.Start();
        if (getF.ThreadState == ThreadState.Stopped)
        {
           //...
        }

那个 if() 语句永远不会执行。线程完成其工作需要时间。您必须插入 getF.Join() 但这会破坏使用线程的意义。

使用 BackgroundWorker 类。

【讨论】:

    【解决方案2】:

    AFAIK,Thread.Start() 在线程启动后立即返回。因此,在检查 ThreadState 之前,您应该等待它完成工作。等待线程完成在This question中讨论过

    【讨论】:

      【解决方案3】:

      在执行条件之前线程很可能不会完成。也就是说,你有:

      getF.Start();
      if (getF.ThreadState == ThreadState.Stopped)
      

      在您测试它是否已停止之前,线程甚至可能不会启动。您必须有某种方式让主线程知道另一个线程完成了它的工作。

      等待线程完成的典型方法是调用Join。那就是:

      getf.Start();
      getf.Join(); // suspends main thread until the child thread is done
      

      但如果你这样做,你会阻止你的用户界面。

      使用多个线程的原因是主线程(在您的情况下为 UI 线程)可以在其他线程执行其工作的同时执行其他操作。我怀疑你想要的是一个BackgroundWorker,它将获取文件,然后在完成后执行一些操作——在RunWorkerCompleted 事件处理程序中。

      【讨论】:

      • 首先我不会使用它,因为这就是我创建线程的原因。其次,如何在使用 backGroundWorker 时以相同的方式返回 files 数组?(我想要一个 return 语句和一个 ArrayList 在 main 方法中检索它)。
      • @agam360:BackgroundWorker 链接有一个很好的例子来说明如何使用它。如果您想要ArrayList,请将其声明为类范围引用并将其填充到BackgroundWorker
      • 那也不好。因为我将使用另一种方法来递归获取此数据,因此我需要该数组列表在类范围内。
      • @agam360:我怀疑你得到的答案是“使用BackgroundWorker”。如果这不可接受,那么您必须提供更多信息,说明您的程序正在做什么以及为什么您认为BackgroundWorker 不起作用。顺便说一句,我确实说过你可以在类范围内定义你的ArrayList。此外,您可能会考虑使用List<string> 而不是ArrayList
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-08
      • 2012-08-12
      • 1970-01-01
      相关资源
      最近更新 更多