0

I develop some USB communication which custom made device. I have use this USB dll to made things easier:

HidLibrary

Very good library but have one little bug. For example if I send something to USB device and device doesnt responde to that (it is not right command, etc.) this dll toolbox waiting for command response to infinity!

Now I like to add some timeout if after some second it no response go further.

I use now method whith bool status response, that I know if reading was successful or not.

var readreport = _choosendevice.ReadReport();

Later I need "readreport" variable, because there inside (readreport.Data) are acceptet data.

My question is how to implement this line into some timeout command? I found already solution for bug, but was not working for me (bug fix link).

If any question please ask. If question is not questioned in the right way, sorry for that because I am beginner in C#. THANKS! for help

esispaned
  • 283
  • 5
  • 20
  • You have 2 things you need to implement here. 1. Wait for a given amount of time, and 2. "kill" the function. How do you intend to do nbr. 2? Have you considered modifying that project and fixing that bug, or reporting it to the author? – Lasse V. Karlsen Aug 11 '15 at 14:20
  • You can wrap calls to that library into a separate dll, then [load](http://stackoverflow.com/q/4887847/1997232) it into another domain, which you can unload in case of timeout. – Sinatr Aug 11 '15 at 14:28
  • Yes I already report the issue to author – esispaned Aug 12 '15 at 04:59

3 Answers3

5

You can use Tasks to do so:

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;

EDIT I didn't know the return value of your function. It returns a HidReport objtect. I just modified the Task creation to fit the return type

As said in comments the library already provides this mechanism so you just can call the right method

HidReport report = await ReadReportAsync(timeout);

** EDIT ** This code gone well for me

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;
Paradise228
  • 717
  • 3
  • 16
  • Sorry. I fix now my post. Now I add right code in post. Sorry for that. Problem is that I need "readreport" variable, because there are writen my data which I may get it or not :) – esispaned Aug 12 '15 at 05:06
  • When the tasks completed you can get the returned result doing this `HidReport report = myTask.Result;` – Paradise228 Aug 12 '15 at 08:30
  • I just checked the source of this library and they have implemented the method you need with a timeout `public HidReport ReadReport(int timeout)` They got an async version too! `public async Task ReadReportAsync(int timeout = 0)` [Source](https://github.com/mikeobrien/HidLibrary/blob/master/src/HidLibrary/HidDevice.cs#L132) – Paradise228 Aug 12 '15 at 08:35
  • Thanks Paradise228, I found that already. But problem is when I debugging there I see results, when I like to define new variable: "var blabla = myTask.Result" - Result is not found, whay is that? – esispaned Aug 12 '15 at 08:36
  • http://stackoverflow.com/questions/15359494/why-is-the-tasks-result-property-unavailable-for-non-generic-task-c-4-0 This i found similar to my problem – esispaned Aug 12 '15 at 08:40
  • About Library ... I test all possible timeouts, non of this works. Thanks! Thanks for time used for checking :) I didnt describe while I did this few hours a go, between posting. – esispaned Aug 12 '15 at 08:45
  • I try this Async method one more time, not working :) – esispaned Aug 12 '15 at 08:58
  • Interestting .. because I have no possibilities to choose "Result". .NET is 4.5.2 – esispaned Aug 12 '15 at 09:00
  • This cannot be the answer as it always waits for the timeout period before quitting. If the function completes before that it must still wait that full time. There is also nothing to kill the task if it runs over. The other [answer](https://stackoverflow.com/a/54024009/16391) is correct – StingyJack Mar 15 '21 at 01:00
2

Late response, but in case someone visits this question:

It's better to use separate tasks for the result and the waiting.

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...
}

That way you do not have to wait for the timeout if the report is ready in time. (And Taks.Delay is better than Task.Wait because it doesn't block)

Remco te Wierik
  • 1,436
  • 2
  • 10
  • 10
0
Task<HidReport> myTask = Task.Factory.StartNew(() => _choosendevice.ReadReport());
myTask.Wait(1000);

if (myTask.IsCompleted)
{
     HidReport report = myTask.Result;
}
else
{
     myTask.Dispose();
     // show ERROR
}

Maybe this will work. Until now was working, just make few tests and then I confirm (I helped with this page this:))

Community
  • 1
  • 1
esispaned
  • 283
  • 5
  • 20
  • Thanks! But not I change your a little bit :) I try now also all possible solution in .net 4.5 version and not .net 4.5.2 (just for sure) and same problems. Because toolbox (HidLibrary) was writen in 4.5. – esispaned Aug 12 '15 at 10:12