gpt4 book ai didi

c# - 在给定时间后等待并终止线程而不阻塞.NET 3.5

转载 作者:太空宇宙 更新时间:2023-11-03 17:00:00 25 4
gpt4 key购买 nike

我有一个 .NET 3.5 上的 WinForms 应用程序。在这种形式下,用户触发在另一个线程(准确地说是 BackgroundWorker)中执行的操作,以免阻塞 UI 线程。我在 MVP 中,所以所有这一切都是由与 View 界面交互的演示者完成的(由 Windows 窗体实现)。到目前为止一切顺利。

我想介绍一种功能,即为后台操作引入超时时间,以便在取消操作之前完成。听起来很简单。但是后台操作调用第三方组件上的单个函数可能永远不会返回,因此 BackgroundWorker 的取消功能在这里对我没有用。此外,BackgroundWorker.RunWorkerCompleted 允许我返回到 UI 线程,因此我需要等待超时或成功并能够返回到我的调用线程(即 UI 线程)。

我尝试使用一个普通的旧线程(它支持Abort())和一个在第二个线程上运行的计时器,但似乎无法得到它可以正常工作,因为 Join() 阻塞了我的 UI 线程,尽管描述表明它将阻塞 "while continuing to perform standard COM and SendMessage pumping "。不可否认,我认为这意味着它会继续处理 Windows 消息,但事实并非如此。

int timeoutInMsec = 10000;
Thread connectThread = new Thread(Connect);
Thread timerThread = new Thread(() =>
{
var timer = new System.Windows.Forms.Timer() { Interval = timeoutInMsec };
timer.Tick += (_s, _e) =>
{
timer.Stop();
if (connectThread.ThreadState == ThreadState.Running)
connectThread.Abort();
};
};

connectThread.Start();
timerThread.Start();
timerThread.Join();
connectThread.Join();

基于 this question ,我尝试删除第二个计时器线程并添加 ManualResetEvent 并在计时器计时或 Connect 方法确实完成时调用 Set() 。在这里,我使用了 WaitOne 而不是 Join,但不幸的是,这也阻塞了我的 UI 线程。我还找到了this other question ,这是一个 CancellationTokenSource,遗憾的是在 .NET 3.5 中不可用。

那么,在 .NET 3.5 中,我如何启动我的工作线程并能够在给定的时间后终止它,同时又能够返回到我启动工作线程的线程执行某种 OnCompleted 处理程序?

非常感谢!

PS:我在 .NET 中的多线程编程方面没有很多经验,所以如果这是微不足道的,我很抱歉。

最佳答案

如果我正确理解你的问题,下面的算法应该可以解决你的问题:

  • 和以前一样,创建一个 BackgroundWorker 来完成您的后台工作。

  • 在 BackgroundWorker_DoWork 中,

    • 创建一个新线程(我们称之为“第三方线程”)来调用您的第三方库,然后
    • 等待第三方线程完成或超时结束。 (*)

这样,您的 UI 就不会阻塞,因为只有 Backgroundworker 线程在等待,而不是主线程。

现在谈谈有趣的部分:如何等待第三方线程完成(标有 (*) 的步骤)?

我的建议是简单地使用“循环等待 sleep ”,即(伪代码,您可以使用 Stopwatch 类作为超时):

do until (third-party thread has finished or x seconds have elapsed):
Thread.Sleep for 100ms

if third-party thread has not finished:
Abort it // we don't have another choice
else
Process the result

这不是最佳实践,但它很简单,它可以完成工作,一旦一切正常,您可以随时将其替换为花哨的跨线程同步东西(要正确实现它并非易事)。

关于c# - 在给定时间后等待并终止线程而不阻塞.NET 3.5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42575654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com