Visual Studio 2015 调试在多线程应用程序中不起作用

Visual Studio 2015 Debug doesn't work in multithread application

在我的项目中,我有大量代码应该在单独的线程上执行而不会阻塞 UI。当调试器遇到此代码中的断点时,VS2015 会冻结 5-10 秒。在那之后,如果我尝试继续调试(通过按 Step Over、Step In 或 Continue),应用程序会从暂停状态变为工作状态,调试工具正在滴答作响,但什么也没有发生并且 CPU 利用率为 0% .如果我然后按 Break All,"cursor"(不知道正确的术语)显示在 Program.cs 中的 Application.Run( new Form1() );,其中 Main() 是。

由于我是 C# 的新手,我认为我的多线程方法存在一些问题,但显然无论我尝试什么都会发生 - 使用 async/await 和任务,使用 BackgroundWorker组件,或简单的 new Thread(myFunc).Start().

澄清一下。

编辑: 每个请求,我不断遇到问题的测试表单代码。只有三个按钮,label 和 BackgroundWorker。整体方案与主工程代码类似

    public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    const int period = 10000;
    void FuncAsync(IProgress<int> progress)
    {
        for ( int i = 0; i < Int32.MaxValue; ++i )
        {
            double part = (double)i / Int32.MaxValue;
            int percent = (int)(part * 100.0);

            if ( (i % period) == 0 )
                progress.Report( percent );
        }
    }
    void FuncBW(BackgroundWorker worker)
    {
        for ( int i = 0; i < Int32.MaxValue; ++i )
        {
            double part = (double)i / Int32.MaxValue;
            int percent = (int)(part * 100.0);

            if ( (i % period) == 0 )
                worker.ReportProgress( percent );
        }
    }
    void FuncThread()
    {
        for ( int i = 0; i < Int32.MaxValue; ++i )
        {
            double part = (double)i / Int32.MaxValue;
            int percent = (int)(part * 100.0);

            if ( (i % period) == 0 )
                label1.Text = percent.ToString();
            //yes, this one will cause exception of accessing UI from different thread
            //if i press "Break" in the exception window, i will also get a 10sec freeze
        }
    }



    private async void button1_Click(object sender, EventArgs e)
    {
        var progress = new Progress<int>(i => label1.Text = i.ToString() );
        await Task.Factory.StartNew( () => FuncAsync( progress ),
                                    TaskCreationOptions.LongRunning );
    }

    private void button2_Click(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
    }

    private void button3_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(FuncThread);
        t.Start();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        FuncBW( (BackgroundWorker)sender );
    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        label1.Text = e.ProgressPercentage.ToString();
    }
}

我建议您在代码中使用 Timer 和 WaitHandle 的组合,而不是导致高 CPU 使用率的 for 循环。我对您的代码做了一个简单的更改,以简化 CPU 的使用。希望有所帮助。

    public partial class Form1 : Form
    {
        EventWaitHandle _waitHandle ;
        System.Timers.Timer _timer; 
        public Form1()
        {
            InitializeComponent();
            _waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
            _timer = new System.Timers.Timer();
            _timer.Interval = 100;
            _timer.Elapsed += OnTimerElapsed;
            _timer.AutoReset = true;

        }

        private void OnTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            _waitHandle.Set();
        }

        void FuncAsync(IProgress<int> progress)
        {
            _timer.Start();
            int percent = 0;
            while (percent <= 100)
            {
                if (_waitHandle.WaitOne())
                {
                    progress.Report(percent);
                    percent++;
                }
            }
            _timer.Stop();

        }
        void FuncBW(BackgroundWorker worker)
        {
            _timer.Start();
            int percent = 0;
            while (percent <= 100)
            {
                if (_waitHandle.WaitOne())
                {
                    worker.ReportProgress(percent);
                    percent++;
                }
            }
            _timer.Stop();
        }



        void FuncThread()
        {
            _timer.Start();
            int percent = 0;
            while (percent <= 100)
            {
                if (_waitHandle.WaitOne())
                {
                    if (this.InvokeRequired)
                    {
                        this.Invoke((Action)delegate { label1.Text = percent.ToString(); });
                    }
                    else
                    {
                        label1.Text = percent.ToString();
                    }
                    percent++;
                }
            }
            _timer.Stop();
        }


        ... your other code
    }

我在调试多线程 WinForms 应用程序时遇到过类似的 VS2015 冻结(无限期)问题。

我在 VS2013 中调试相同的代码没有问题。

当我禁用 VS 托管进程(项目 -> 属性 -> 调试 -> 启用 Visual Studio 托管进程)时,问题似乎消失了。

希望对其他人有用。

在 options-debugging-general 中检查 "use managed compatibility mode" 后,线程调试似乎可以工作。

我在 2 个不同的线程中设置了断点,Visual Studio 在我逐步执行时从一个线程跳到另一个线程。最终它在标题栏中冻结为 (Not Responding)。

如果我将断点限制在一个线程,我就不会遇到这个问题。

我遇到了类似的问题。这个问题的其他答案并没有为我解决问题,但它们为我指明了正确的方向。显然我选择了 Release 配置,而不是 Debug.

即使在禁用托管进程后,我也遇到了 visual studio 2008 冻结的问题。似乎对我有用的是禁用地址级调试。

(VS2008) 工具(菜单)-> 选项-> 调试-> 常规->(取消选中)启用地址级调试。

经过烦人的几个小时,@Haggisatonal 的回答对我来说就是这样。非常感谢!

The problem appears to go away when I disable the VS hosting process (Project -> Properties -> Debug -> Enable the Visual Studio hosting process).

但是

"Tools -> Options -> Debugging -> General -> Enable property evaluation and other implicit function calls"

就像另一个票证一样,不是我的解决方案,也许它能暂时帮助其他人