如何使非空返回方法超时,并在挂起时终止其执行

本文关键字:挂起 终止 执行 何使非 返回 方法 超时 | 更新日期: 2023-09-27 18:15:21

我有一个与HID设备通信以检索序列号的方法,但是,如果HID设备"存在"但不活动,则与BT一起工作时常见,对串行的调用将阻塞并只是坐在那里。

我想调用我的方法,但它超时了,如果失败,返回一个空序列,如果成功,返回正确的序列。

任务。Run完成了大部分工作,但如果任务挂起,则不会杀死该任务,从而使我的应用程序无法退出。

        var task = Task.Run(() => GetSerialStringWorker(device));
        if (task.Wait(TimeSpan.FromMilliseconds(300)))
            return task.Result;
        else
        {
            //Need to be able to kill the task here!
            return "00:00:00:00:00:00";
        }

取消令牌也不能使用,因为获取序列的代码是外部库的一部分,并且不接受取消。

也试过这个,但是它阻塞在thread. join()上,并且在线程终止时不能正确释放;

        string sn = "00:00:00:00:00:00";
        System.Timers.Timer timeoutTimer = new System.Timers.Timer() { Interval = 300 };
        Thread thread = new Thread(() =>
        {
            sn = GetSerialStringWorker(device);
            timeoutTimer.Stop();
        });
        timeoutTimer.AutoReset = false;
        timeoutTimer.Elapsed += (s, e) => { thread.Abort(); };
        timeoutTimer.Start();
        thread.Start();
        thread.Join();
        return sn;

好吧,不管出于什么原因,上面例子中的Join使我的应用程序无法完全加载,只是在那里阻止了应用程序的其他初始化。解决方案是使用while命令阻塞它;

        string sn = "";
        Thread thread = new Thread(() =>
        {
            sn = GetSerialStringWorker(device);
        });
        var timeoutTimer = new System.Threading.Timer((s) =>
        {
            thread.Abort();
            sn = "00:00:00:00:00:00";
        }, null, 500, Timeout.Infinite);
        thread.Start();
        while (sn == "")
        {
            Thread.Sleep(1);
        }
        return sn;

这感觉真的很难看,但现在它可以工作,直到有人想出一个更好的方法。

如何使非空返回方法超时,并在挂起时终止其执行

你的问题似乎是你想取消一个不可取消的异步操作,看看这里可能实现的技术:

如何取消不可取消的异步操作

也看看这个答案https://stackoverflow.com/a/14524565/7070657