如何在Delphi多线程代码中改进调试过程?

时间:2017-11-09 14:25:32

标签: multithreading delphi debugging delphi-10-seattle

我正在从这些问题中学习这两个例子

我用什么技术来调试?

  • 阅读代码并推测它将如何失败。

  • 编译代码并让它运行,看看我是否正确。

这让我在第二个答案中找到了一个错误。这是我的评论:

  

您显示的示例有一个错误:如果您让任务完成它   将在标签上显示任务终止,而不是因为您完成任务   在设置标签的标题后调用btnCancelTaskClick(Self);   完成任务会破坏将唤醒的线程   取消事件并打破循环导致发布第二个   消息将更改标题到任务终止。解决方案   将是在调用之前添加此行if not readyFlag then   第二个postmessage。我建议编辑我希望你不介意

我现在使用的是什么技术?

  • 第一种技巧。
  • 在任何地方放置断点并按Ctrl + Alt + T查看每个线程的统计信息。

现在,事情开始显现出丑陋的一面。我开始明白线程以非同步的方式运行(首先运行的线程将保持为???)。这些是我从第一个答案得到的结果。

重现的示例

创建一个新的VCL项目并在主窗体上添加两个TButtons。第一个按钮创建线程,第二个按钮释放它。

procedure TForm6.Button1Click(Sender: TObject);
begin
th.Free;
end;

procedure TForm6.Button2Click(Sender: TObject);
begin
  th := TMyThread.Create;
end;

按下Button2,然后按下Button1,看看你能得到什么

结果(在调试器下):

  • 在第一次运行中,我得到GetLastError = 6 = ERROR_INVALID_HANDLE。 奇怪的是,当主线程(主线程是执行销毁代码的线程)中的TEvent在析构函数中被销毁时,TEvent.WaitForMultiple的结果不是wrAbandoned

  • 在第二轮比赛中,我什么也没得到,线程被正确终止。

  • 在第三次运行中,代码停留在CheckPause方法上,因为TEvent.WaitForMultiple返回wrAbandoned并且它一直在内部循环,直到终止为True。

在没有调试器的情况下启动第二个答案时,10次运行都没有发生任何事情。

结论:我承认调试多线程应用程序是一场噩梦。我可以设计一个没有错误类的正确非死锁的最好方法也是一场噩梦。

从现在开始检查终止将是我的模式。

我从调试器中获得的错误总是在我从其中启动代码时出现(不知道为什么?我检查了异常是否被其他地方吞没但没有成功)。

问题如何在Delphi多线程代码中改进调试过程?所以我得到了更多这些错误。

0 个答案:

没有答案