【发布时间】:2024-07-20 15:50:02
【问题描述】:
我一直在尝试创建一个在不阻塞 UI 线程的情况下写入数据库的任务。我遇到的最大问题是等待该进程完成而不会发生阻塞。
我一直在努力避免使用DoEvents(虽然现在通过这个程序非常频繁地使用它,但我想在继续前进的同时停止使用它)。
我尝试创建进程以在第二个线程上运行并等待它完成以及使用BackgroundWorker。
我遇到的问题不是让代码在不同的线程中运行,而是试图找到一种方法来等待它完成。
基本上,现在我执行以下操作:
- 连接到数据库
- 创建一个后台工作者(或线程)来写入数据库(我可能最终会使用
BackgroundWorker,所以我可以使用ReportProgress - 启动线程或
BackgroundWorker - 使用 While 循环等待线程 /
BackgroundWorker完成。对于线程,我等待IsAlive变为 false,对于BackgroundWorker,我切换一个布尔变量。 - 我让用户知道该过程已完成。
问题出在#4。
执行没有代码的 while 循环,或者 Thread.Sleep(0) 使 UI 被阻塞(Thread.Sleep(0) 使程序也占用 100% 的程序资源)
所以我这样做:
while (!thread.IsAlive)
Thread.Sleep(1);
-或-
while (bProcessIsRunning)
Thread.Sleep(1);
这会阻止 UI。
如果我在那里调用Application.DoEvents(),UI 会更新(虽然它是可点击的,所以我必须在此过程运行时禁用整个表单)。
如果我同步运行该过程,我仍然需要创建某种方式来更新 UI(在我看来,是一个 DoEvents 调用),因此它看起来不会被锁定。
我做错了什么?
【问题讨论】:
-
欢迎来到Stack Overflow。几件小事: 1. 请不要在标题前加上“C# .NET (3.0)”之类的东西。这就是Stack Overflow 上使用的标签。 2. 请不要签名。 3.说到标签,你应该通过添加适当的标签告诉我们你是使用winforms还是wpf或其他什么。
-
抱歉,我不知道用什么来标记它,并且用 5 标记上限,我没有放它。我正在使用 Winforms(现在是一个标签)
-
@JohnSaunders:我强烈不同意您在标题中不包含标签(例如 C# .NET WinForms)的建议。原因:Google 是人们访问 * 页面的最常见方式。拥有包含此类上下文的标题可以更快地确定问答是否相关。
-
@ToolmakerSteve:你错了。 Stack Overflow 已经将顶部标签放入标题中,如 Google 所见。
-
@JohnSaunders:如果标签直接列在标题下方,那么 POV 将是明智的。但他们不是。这不是“噪音”!一个人必须扫描到一个可能很长的问题的结尾才能找出问题的关键背景,知道一个人是否关心这个问题,这种想法完全是错误的。
标签: c# .net winforms multithreading doevents