[英]Visual Studio 2015 Debug doesn't work in multithread application
在我的項目中,我有很多代碼應該在一個單獨的線程上執行而不會阻塞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#很陌生,我認為我的多線程方法存在一些問題,但顯然它發生在我嘗試的任何地方 - 使用async / await與Tasks,使用BackgroundWorker
組件或簡單的new Thread(myFunc).Start()
。
只是為了清楚。
for ( int i = 0; i < Int32.MaxValue; ++i )
函數的全新解決方案中檢查了它 - 同樣的問題。 編輯:每個請求,測試表的代碼,我不斷得到問題。 只有三個按鈕,標簽和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();
}
}
在調試多線程WinForms應用程序時,我遇到了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<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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.