Visual Studio 2015 Debug doesn't work in multi

2019-03-11 05:36发布

In my project I have a heavy part of code that should be executed on a separate thread without blocking UI. When debugger hits the breakpoint inside this code, VS2015 freezes for 5-10 seconds. After that, if I try to continue debug (by pressing Step Over, Step In or Continue), the app goes from paused state to working state, Debugging Tools are ticking, but nothing happens and there's 0% of CPU utilization. If I press Break All then, the "cursor" (don't know the correct term) is shown at Application.Run( new Form1() ); in Program.cs where Main() is.

As I'm pretty new to C#, I thought that there was some problem with my approach to multithreading, but apparently it happens whatever I try - using async/await with Tasks, using BackgroundWorker component, or simple new Thread(myFunc).Start().

Just to be clear.

  • The code itself works perfectly fine.
  • Debugger itself also works, no freezes and "deadlocks" on breakpoints in my main thread. If I launch the code from main thread - everything is fine.
  • I also checked it in a fully new solution on a simple for ( int i = 0; i < Int32.MaxValue; ++i ) function - same problem.
  • Also checked on different versions of .NET: 4.6, 4.5, 4.0. Same everywhere.
  • The problem doesn't appear neither in VS2010 (which I used before), nor in VS2013 (which I tried just to be sure that it's a VS2015 problem). However, my friend working with the same VS2015 also doesn't have this problem.

Edit: per request, code of test form where I keep getting the problem. Only three buttons, label, and BackgroundWorker. The overall scheme is similar to the code of the main project.

    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();
    }
}

7条回答
Summer. ? 凉城
2楼-- · 2019-03-11 05:57

I've experienced similar issues with VS2015 freezing (indefinitely) whilst debugging a multi thread WinForms application.

I had no problems debugging the same code in VS2013.

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

Hope that works for others.

查看更多
再贱就再见
3楼-- · 2019-03-11 06:05

After i checked "use managed compatibility mode" in options-debugging-general, thread debugging seems to work.

查看更多
虎瘦雄心在
4楼-- · 2019-03-11 06:05

After annoying hours, the answer of @Haggisatonal was it for me. Thank you very much!

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

but

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

like in a nother Ticket, was not the resolution for me, maybe it helps temporairly others

查看更多
地球回转人心会变
5楼-- · 2019-03-11 06:05

I had the problem of visual studio 2008 freeze even after disabling the hosting process. What seems to be working for me is disabling address level debugging.

(VS2008) Tools (menu) -> Options -> Debugging -> General -> (uncheck) Enable address-level Debugging.

查看更多
劫难
6楼-- · 2019-03-11 06:11

I had breakpoints in 2 different threads and Visual Studio was bouncing from one to the other as I stepped through. Eventually it froze with (Not Responding) in the title bar.

If I limited the breakpoints to just one thread, I would not experience the problem.

查看更多
Rolldiameter
7楼-- · 2019-03-11 06:12

I suggest that you use a combilation of a Timer and WaitHandle in your code instead of the for loop that causes high CPU usage. I made a simple change to your code to ease the CPU usage. Hope that help.

    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
    }
查看更多
登录 后发表回答