Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使非void返回方法超时,并在挂起时终止其执行?_C# - Fatal编程技术网

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

C# 如何使非void返回方法超时,并在挂起时终止其执行?,c#,C#,我有一种与HID设备通信以检索序列号的方法,但是,如果HID设备“存在”,但不像与BT一起工作时那样处于活动状态,则对序列号的调用将被阻止,并且只是停留在那里 我想调用我的方法,但让它超时,如果失败则返回空序列,如果成功则返回正确的序列 Run可以完成大部分任务,但如果任务挂起,则不会终止任务,从而使我的应用程序无法退出 var task = Task.Run(() => GetSerialStringWorker(device)); if (task.Wa

我有一种与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;
好吧,不管出于什么原因,上面示例中的连接都会阻止我的应用程序完全加载,并阻止其余的应用程序初始化。解决方案是使用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;

这感觉真的很难看,但目前它仍然有效,直到有人能找到更好的方法。

您的问题似乎是要取消一个不可取消的异步操作,请查看此处,以找到一种可能的技术来实现这一点:


再看看这个答案

看看这个答案:@OrangeKing89正如我所说的,任务不允许堕胎。我想你可以用事件机制替换.Join()。但是中止线程对于资源来说总是值得怀疑的。也许这会有所帮助,因为您(显然)正在处理第三方/非托管代码,您的选择是有限的。中止线程是一个非常糟糕的主意,但让线程无限期地处于活动状态也是一个非常糟糕的主意。有关可用的较差选项的讨论,请参见标记的副本。有关处理不可取消的第三方呼叫的信息,请参阅。本节还讨论了不可中止的任务。