C# 无法单步执行异步任务
我曾试图通过大量类似的“如何调试异步任务”的帖子和文章来实现这一点,但仍然无法在我的WPF应用程序的异步方法中进入或获取要触发的断点。无论我如何启动或运行任务,或是否选择了CLR异常 至于为什么要执行任务,我真的只希望我的WPF应用程序的UI在工作完成时保持响应,以便在应用程序思考时可以使用UI将其他工作排队 更新1:如果后面出现一行代码,断点似乎没有被命中?!?!断点引发异常。 它本身的异常只是一个File.IO异常,我将很快修复它,其中有相当多的文件操作需要排序,其中一个作为请求的最小示例包括在内。异常不包含堆栈跟踪来确定抛出它的特定行,而无需手动注释它们,一次一行 具体来说,C# 无法单步执行异步任务,c#,wpf,asynchronous,task,C#,Wpf,Asynchronous,Task,我曾试图通过大量类似的“如何调试异步任务”的帖子和文章来实现这一点,但仍然无法在我的WPF应用程序的异步方法中进入或获取要触发的断点。无论我如何启动或运行任务,或是否选择了CLR异常 至于为什么要执行任务,我真的只希望我的WPF应用程序的UI在工作完成时保持响应,以便在应用程序思考时可以使用UI将其他工作排队 更新1:如果后面出现一行代码,断点似乎没有被命中?!?!断点引发异常。 它本身的异常只是一个File.IO异常,我将很快修复它,其中有相当多的文件操作需要排序,其中一个作为请求的最小示例包
const string APP_REG_NAMESPACE = "[Redacted]";
IProgress<int> progress;
IProgress<string> status;
public MainWindow() {
InitializeComponent();
this.DataContext = this;
//Allows UI to remain responsive while work is being done.
progress = new Progress<int>(UpdateProgress);
status = new Progress<string>(UpdateStatus);
//exceptions only appear here.
Task.Run(() => EvalConfig(progress, status));
}
/*Removed as seemed un-needed
async Task Async_EvalConfig() {
progress = new Progress<int>(UpdateProgress);
status = new Progress<string>(UpdateStatus);
//exceptions all thrown here.
await Task.Run(() => EvalConfig(progress, status));
}*/
//This allows breakpoints to be hit on any of the 3 lines
void EvalConfig(IProgress<int> progress, IProgress<string> status) {
//Give system a second (or 10)
Task.Delay(5000);
Thread.Sleep(5000);
return;
}
//No breakpoints are ever hit, if an exception occurs anywhere,
//even if on only the last line.
//Exceptions are only shown at the line that actually runs the task.
void EvalConfig(IProgress<int> progress, IProgress<string> status) {
//Give system a second
await Task.Delay(500);
cancellationTokenSource = new CancellationTokenSource();
//Some long duration IO work done here to prepare data load.
//[Redacted for brevity]
//Check the registry for the protocol key
if(TryGetProtocol(out string protocol)){
//Use the protocol to connect and start doing some painfully slow work
//[Truncated for brevity]
}else{
//Handle missing protocol logging and schedule for admin repair.
//[Truncated for brevity]
}
}
bool TryGetProtocol(out string strProtocol) {
strProtocol = "";
try {
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(APP_REG_NAMESPACE)) {
if (key == null) {
return false;
} else {
Object o = key.GetValue("");//AKA (Default)
if (o == null) {
return false;
}
strProtocol = (o as String);
if (string.IsNullOrEmpty(strProtocol)) {
return false;
}
}
}
//Oddly this didn't actually catch the error
//despite being super generic.
} catch (Exception ex) {
//Handle notification of exception.
//[Truncated for brevity]
return false;
}
return true;
}
这不是一个真正的答案,但我最接近于再次命中断点 如果在任务的线程中的任何位置引发异常,则在任务/异步代码上似乎不会命中断点。这个奇怪的行为调试器是由一个未处理的异常引起的,即使该异常发生在?!?!断点
对于未来的搜索者,在清除所有未处理的异常之前,您可能无法使用VS调试器单步执行任务代码。即使程序编译得很愉快也要删除任务。围绕异步方法运行包装器。等待评估配置程序、状态;异步_EvalConfig.GetAwaiter.GetResult;但这完全是错误的。它会阻止执行,因此表单永远不会显示。如果MyCollection是一个字段或属性,它将永远不会得到任何值,因为窗口的构造函数在Async\u EvalConfig完成之前不会完成。将Async\u EvalConfig返回的任务分配给一个字段,并仅在您确实需要等待它完成时才等待它。@Reahreic:请发布一个最小的复制,然后我们就可以看到问题所在。@Reahreic您发布的代码中的错误在构造函数中,而不是在循环中。如果这不是真正的代码,发布一些重现实际问题的内容。你不需要做任何特殊的事情来完成任务并取得进展。你不需要过时的后台工作人员。BGW更难使用,无法组合任务。@Reahreic wait用于避免阻塞。如果使用.Result、.Wait或.GetAwaiter.GetResult,则显式阻止