R
RazvanCS
Guest
I would like to call asynchronously from a Form (a UI Thread - MAIN_UITh) a function (F2) to run in another UI Thread - Second_UITh (another Form) having also ability to timeout. Of course - the function in the Second_UITh will not finish after the timeout occurs, but the async call will continue in MAIN_UITh. I found different implementations for the timeout ( (1) The Task-based Asynchronous Pattern Stephen Toub, Microsoft February 2012), (2) Crafting a Task.TimeoutAfter Methodby Joe Hoag. The idea is to:
() => F2(p1,p2) ,
combinedCTS.Token,
TaskCreationOptions.DenyChildAttach,
TaskSchedulerForm);
if (completedTask == workingTask)
{
// workingTask done in time
// return the result of the workingTask
}
else
{
//timeout
}
The problem that I have is that if F2(...) function is blocking (simulated with a Thread.Sleep) the whole step 1 Task.Factory.StartNew
is blocking and I cannot start the awaiting for the Timeout (step 2).
If F2(...) is not blocking then everything runs as expected.
Details:
- the TaskSchedulerForm variable is initialized in the constructor of the second Form (that runs in Second_UITh)
TaskSchedulerForm = TaskScheduler.FromCurrentSynchronizationContext();
- The function F2(...) runs in Second_UITh. But it has to finish and only after that the second step is able to run
- The synchronous part (first part before the Task.Factory.StartNew<int>) runs as expected in the MAIN_UITh. Since I don't have a await in the call of Task.Factory.StartNew<int> and F2(...) runs (or it is scheduled) to run on a different thread, I expect the code of second step (await Task.WhenAny) to execute before the F2(...) finishes.
- if I remove the Sleep from F2(...) then it is working as expected.
- The F2(...) can be a function from a third party library which not implement (or at least not in a consistent manner) a timeout feature. It involves some socket communication but I don't know the details (it is not a full CPU-bound task). The library can be an ACTIVEX component - but in my test case F2 is just a simply blocking function.
- I tried also a make F2 async. (and the the StartNew becomes <Task<int>> with all the Unwrap() spill)
Thanks,
Razvan
Continue reading...
- launch async the function (Func<TResult>) using the only method that allows to use the TaskScheduler.FromCurrentSynchronizationContext() of the Second_UITh which is Task.Factory.StartNew. Based on the Startnew is dangerous by Stephen Cleary my case represents a good reason to use the "dangerous" function
() => F2(p1,p2) ,
combinedCTS.Token,
TaskCreationOptions.DenyChildAttach,
TaskSchedulerForm);
- await for any of the two task:
if (completedTask == workingTask)
{
// workingTask done in time
// return the result of the workingTask
}
else
{
//timeout
}
The problem that I have is that if F2(...) function is blocking (simulated with a Thread.Sleep) the whole step 1 Task.Factory.StartNew
is blocking and I cannot start the awaiting for the Timeout (step 2).
If F2(...) is not blocking then everything runs as expected.
Details:
- the TaskSchedulerForm variable is initialized in the constructor of the second Form (that runs in Second_UITh)
TaskSchedulerForm = TaskScheduler.FromCurrentSynchronizationContext();
- The function F2(...) runs in Second_UITh. But it has to finish and only after that the second step is able to run
- The synchronous part (first part before the Task.Factory.StartNew<int>) runs as expected in the MAIN_UITh. Since I don't have a await in the call of Task.Factory.StartNew<int> and F2(...) runs (or it is scheduled) to run on a different thread, I expect the code of second step (await Task.WhenAny) to execute before the F2(...) finishes.
- if I remove the Sleep from F2(...) then it is working as expected.
- The F2(...) can be a function from a third party library which not implement (or at least not in a consistent manner) a timeout feature. It involves some socket communication but I don't know the details (it is not a full CPU-bound task). The library can be an ACTIVEX component - but in my test case F2 is just a simply blocking function.
- I tried also a make F2 async. (and the the StartNew becomes <Task<int>> with all the Unwrap() spill)
Thanks,
Razvan
Continue reading...