【问题标题】:After adding multi threading to my app, VS2010 will not remove file handle after stopping debugging在我的应用程序添加多线程后,VS2010 停止调试后不会删除文件句柄
【发布时间】:2013-04-07 18:04:25
【问题描述】:

今天我在一个 Windows 窗体应用程序中添加了多线程。在我的 UI 线程上,我正在通过 new Thread() {...}).Start();它本身将调用一个使用 ThreadPool.QueueUserWorkItem() 的方法。调用方法后,线程将在队列中等待,直到返回特定项目并退出:

new Thread(o =>
        {
            s.SimulateChanges();

            Boolean run = true;

            while (run)
            {
                SimulationResult sr = queue.WaitDequeue();

                //EOF is a static property which will be returned 
                //if the queue is at its end so I can break the while loop
                if (SimulationResult.EOF.Equals(sr))
                {
                    run = false;
                    continue;
                }

                this.simulationProgressBar.BeginInvoke((Action)delegate()
                {
                    if (sr.IsDummy && this.simulationProgressBar.Value < this.simulationProgressBar.Maximum)
                    {
                        /*...*/
                    }
                    else
                    {
                        this.resultListView.AddObject(sr);
                    }
                });
            }

            this.simulationProgressBar.BeginInvoke((Action)delegate()
            {
                this.ToggleSimulationControls(true);
            });
        }).Start();

这就是被调用方法的代码:

public void SimulateChanges()
{
    ThreadPool.QueueUserWorkItem(o =>
        {
            foreach (IColElem elem in collection.AsEnumerable())
            {

                /*lot of code*/

                queue.Enqueue(new SimulationResult() { IsDummy = true });

            }
            log.Debug("Finished!");

            queue.Enqueue(SimulationResult.EOF);

        });
}

我的队列是一个自写的类,它允许线程等待出队,直到一个对象入队。

一切正常,除了如果我停止调试(使用停止调试或简单地关闭应用程序)我无法重建我的应用程序,因为 VS2010 不会删除文件句柄。我相信这与我的线程没有正确退出有关。他们有什么办法可以保证吗?

感谢您的建议 :-)

【问题讨论】:

  • 你得到什么错误?正在使用哪个文件?
  • 我的项目的输出程序集:错误:进程无法访问该文件,因为它正在被另一个进程使用。如果我尝试删除文件或清理解决方案,则会出现同样的错误。
  • 删除创建线程的代码后错误是否消失?
  • 更重要的是,您在任务管理器中看到您的应用程序的进程了吗?它真的在运行吗?

标签: multithreading winforms visual-studio-2010


【解决方案1】:

很难解释问题的所有方面。但是你犯了一个很常见的错误,通常是程序员第一次开始使用线程时犯的。当用户关闭主窗口时,您不能确保线程停止运行。这是一个容易犯的错误,UI 线程处理了很多繁重的工作。包括在用户关闭应用程序的主窗口时自动终止。所以至少你的部分问题是你确实设法关闭了主窗口。但实际上并没有终止该过程。无法构建,您的程序的 EXE 仍在使用中。

正确关闭线程可能非常困难,因为无论线程在做什么,用户都会关闭窗口。它可能是紧张的,深埋在操作系统调用中并等待它完成。当它不执行代码时很难要求它退出。

有一个非常简单的解决方案,至少足以继续您的项目或解决您遇到的一半问题。您可以将线程标记为“程序终止时自动终止”,CLR 会处理它。使用 IsBackground 属性,如下所示:

var t = new Thread(o =>
        {
           // Lotsa code
        });
t.IsBackground = true;
t.Start();

但请记住,这种杀戮没有什么优雅的。如果您正在编写文件或与服务器通信,那么这将导致部分写入的文件或非常混乱的服务器。否则和用任务管理器杀掉程序没什么区别。

【讨论】:

  • 哇,感谢您的全面回答。它确实奏效了!现在我可以再次编译而无需每次都重新启动 VS2010。我现在必须看看为什么我的帖子没有按预期结束。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-28
  • 2015-07-03
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多