Visual Studio 2015 Debug在multithreading应用程序中不起作用

在我的项目中,我有很多代码应该在一个单独的线程上执行而不会阻塞UI。 当调试器命中此代码中的断点时,VS2015会冻结5-10秒。 之后,如果我尝试继续调试(通过按Step Over,Step In或Continue),应用程序将从暂停状态进入工作状态,调试工具正在滴答作响,但没有任何反应,CPU利用率为0%。 如果我按Break All然后,在Application.Run( new Form1() );显示“光标”(不知道正确的术语Application.Run( new Form1() ); 在Program.cs中Main()是。

由于我对C#很新,我认为我的multithreading方法存在一些问题,但显然它发生在我尝试的任何地方 – 使用async / await与Tasks,使用BackgroundWorker组件或简单的new Thread(myFunc).Start()

只是要清楚。

  • 代码本身非常好用。
  • 调试器本身也可以工作,在主线程中的断点上没有冻结和“死锁”。 如果我从主线程启动代码 – 一切都很好。
  • 我还在一个简单的for ( int i = 0; i < Int32.MaxValue; ++i )函数的全新解决方案中检查了它 – 同样的问题。
  • 还检查了不同版本的.NET:4.6,4.5,4.0。 到处都是。
  • 这个问题既没有出现在VS2010(我之前使用过)中,也没出现在VS2013中(我试图确保它是VS2015的问题)。 但是 ,我的朋友使用相同的VS2015也没有这个问题。

编辑:每个请求,测试表的代码,我不断得到问题。 只有三个按钮,标签和BackgroundWorker。 整体方案类似于主项目的代码。

  public partial class Form1 : Form { public Form1() { InitializeComponent(); } const int period = 10000; void FuncAsync(IProgress 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(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(); } } 

在调试multithreadingWinForms应用程序时,我遇到了VS2015冻结(无限期)的类似问题。

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

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

希望对别人有用。

我在options-debugging-general中检查了“使用托管兼容模式”之后,线程调试似乎工作正常。

我在两个不同的线程中有断点,当我走过时,Visual Studio从一个跳到另一个。 最终它在标题栏中以(无响应)冻结。

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

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

烦人的时候,@ Haggisatonal的答案就是我。 非常感谢你!

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

“工具 – >选项 – >调试 – >常规 – >启用属性评估和其他隐式函数调用”

就像在另一张票中一样,对我来说不是解决方案,也许它可以帮助临时其他人

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

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

我建议您在代码中使用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 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 }