如何挂起非void返回方法并在挂起时终止它的执行?

时间:2016-10-28 14:57:15

标签: c#

我有一种与HID设备通信以检索序列号的方法,但是如果HID设备是"存在"但是在使用BT时常常没有激活,对串口的调用会阻塞并且只是坐在那里。

我想调用我的方法,但如果失败则返回空序列,如果成功则返回正确的序列。

Task.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";
        }

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

也尝试了这个,但它阻塞了线程.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;

这感觉真的很丑,但现在它起作用,直到有人能想出更好的方法。

1 个答案:

答案 0 :(得分:-1)

您的问题似乎是要取消不可取消的异步操作,请查看此处可能的技术来实现:

How do I cancel non-cancelable async operations

另请查看此答案https://stackoverflow.com/a/14524565/7070657