【问题标题】:Implement Timeout for function C#为函数 C# 实现超时
【发布时间】:2015-08-11 14:18:45
【问题描述】:

我开发了一些定制设备的 USB 通信。我使用这个 USB dll 让事情变得更简单:

HidLibrary

非常好的库,但有一个小错误。例如,如果我向 USB 设备发送了一些东西并且设备没有响应(它不是正确的命令等),这个 dll 工具箱正在等待对无限的命令响应!

现在我想添加一些超时,如果几秒钟后没有响应继续进行。

我现在使用带有布尔状态响应的方法,我知道读取是否成功。

var readreport = _choosendevice.ReadReport();

稍后我需要“readreport”变量,因为里面 (readreport.Data) 是接受数据。

我的问题是如何将此行实现为一些超时命令?我已经找到了错误的解决方案,但对我不起作用 (bug fix link)。

如果有任何问题,请提出。如果问题没有以正确的方式受到质疑,很抱歉,因为我是 C# 的初学者。 谢谢!寻求帮助

【问题讨论】:

  • 你有两件事需要在这里实现。 1.等待给定的时间,2.“杀死”该功能。你打算怎么做nbr。 2?您是否考虑过修改该项目并修复该错误,或​​将其报告给作者?
  • 您可以将对该库的调用封装到一个单独的 dll 中,然后将 load 封装到另一个域中,在超时时可以将其卸载。
  • 是的,我已经向作者报告了这个问题

标签: c# timeout


【解决方案1】:

您可以使用任务来执行此操作:

Task<HideReport> myTask = Task.Factory.StartNew(() => _choosendevice.ReadReport(););
myTask.Wait(100); //Wait for 100 ms.

if (myTask.IsCompleted)
    Console.WriteLine("myTask completed.");
else
    Console.WriteLine("Timed out before myTask completed.");

HidReport report = myTask.Result;

编辑我不知道你的函数的返回值。它返回一个 HidReport 对象。我刚刚修改了任务创建以适应返回类型

正如 cmets 中所说,该库已经提供了这种机制,因此您可以调用正确的方法

HidReport report = await ReadReportAsync(timeout);

** 编辑 **这段代码对我来说很顺利

HidDevice device = HidDevices.Enumerate().ToList().First(e =>e.Description.Contains("mouse"));

Task<HidReport> t = Task.Factory.StartNew(() => device.ReadReport(1000));

t.Wait();

HidReport report = t.Result;

【讨论】:

  • 对不起。我现在修复我的帖子。现在我在帖子中添加正确的代码。对此感到抱歉。问题是我需要“readreport”变量,因为有我的数据我可能会得到它:)
  • 任务完成后,你可以得到返回的结果HidReport report = myTask.Result;
  • 我刚刚检查了这个库的源代码,他们已经实现了你需要的超时方法public HidReport ReadReport(int timeout) 他们也有一个异步版本! public async Task&lt;HidReport&gt; ReadReportAsync(int timeout = 0)Source
  • 感谢 Paradise228,我已经找到了。但问题是当我在那里调试时看到结果,当我想定义新变量时:“var blabla = myTask.Result” - 找不到结果,那是什么?
  • stackoverflow.com/questions/15359494/… 我发现这与我的问题相似
【解决方案2】:

回复较晚,但万一有人访问此问题:

对于结果和等待,最好使用单独的任务。

var waitTask = Task.Delay(timeoutInMs);
Task<MyReport> reportTask = Task.Factory.StartNew(() => _choosendevice.ReadReport(););            
await Task.WhenAny(waitTask, reportTask );
if (reportTask.IsCompleted)
{
  return await reportTask;
}
else
{
  // preferred timeout error handling...
}

这样,如果报告及时准备好,您就不必等待超时。 (而且 Taks.Delay 比 Task.Wait 更好,因为它不会阻塞)

【讨论】:

    【解决方案3】:
    Task<HidReport> myTask = Task.Factory.StartNew(() => _choosendevice.ReadReport());
    myTask.Wait(1000);
    
    if (myTask.IsCompleted)
    {
         HidReport report = myTask.Result;
    }
    else
    {
         myTask.Dispose();
         // show ERROR
    }
    

    也许这会奏效。到现在为止都可以工作,只需进行一些测试,然后我确认(我帮助了这个页面this:))

    【讨论】:

    • 谢谢!但不是我改变了你的一点点:) 我现在也在 .net 4.5 版本中尝试所有可能的解决方案,而不是 .net 4.5.2(只是肯定的)和同样的问题。因为工具箱(HidLibrary)是4.5写的。
    猜你喜欢
    • 2021-01-21
    • 1970-01-01
    • 2010-10-27
    • 2017-03-25
    • 2014-05-23
    • 2011-06-28
    • 2011-08-09
    • 2013-05-06
    相关资源
    最近更新 更多