Reputation: 3470
I would like to translate the C# method DelayNe below to an F# function in such a way that it can be used from C# in exactly the same way. The reason is that I want to put it in an F# library. I am struggling a lot trying to google my way to an answer, with no luck obviously.
Update: Sorry for not being clear. I have tasks that call Task.Delay in the way that you see in the DelayNe method below. The problem is that when _cancellationTokenSource.Cancel() is called, then Task.Delay throws an exception, and I don't want that exception. In other words, I believe I need a wrapper around Task.Delay which will catch the exception and silence it, but otherwise expose the behavior of Task.Delay exactly as is. And I want to implement the wrapper in F#.
private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
async Task DelayNe(int milliSeconds, CancellationToken token)
{
try
{
await Task.Delay(milliSeconds, token);
}
catch (TaskCanceledException ex)
{
("Silencing " + ex.GetType().Name + ", " + ex.Message).Dump();
}
}
async Task Test(CancellationToken cancellationToken)
{
try
{
"Test start".Dump();
await DelayNe(5000, cancellationToken);
"Test stop".Dump();
}
catch (Exception ex)
{
("Catch: " + ex.Message + ", " + ex.GetType().Name).Dump();
}
}
async Task Main()
{
"Start".Dump();
_cancellationTokenSource.CancelAfter(1000);
var testTask = Test(_cancellationTokenSource.Token);
await testTask;
"Stop".Dump();
}
Upvotes: 2
Views: 396
Reputation: 243051
F# asynchronous workflows have built-in support for cancellation, so using those instead of working with tasks will probably make your life a lot easier. Your question does not really provide enough information to understand what you are trying to do, but below is an example of using async
for something that is very close to your example:
let delayNe ms = async {
use! _d = Async.OnCancel(fun () ->
printfn "cancelled!")
do! Async.Sleep(ms) }
let test = async {
printfn "Test start"
do! delayNe 5000
printfn "Test stop" }
let DoWork () =
let cts = new System.Threading.CancellationTokenSource()
cts.CancelAfter(1000)
Async.StartAsTask(test, cancellationToken = cts.Token)
The DoWork
function starts the work as a task, which can be easily consumed from C#.
Upvotes: 6