我想将下面的C#方法DelayNe转换为F#函数,以便以完全相同的方式从C#中使用它。原因是我想把它放在一个F#库中。我正在苦苦挣扎,试图用谷歌来回答答案,显然没有运气。
更新:抱歉不清楚。我的任务以您在下面的DelayNe方法中看到的方式调用Task.Delay。问题是当调用_cancellationTokenSource.Cancel()时,Task.Delay会抛出异常,我不想要那个异常。换句话说,我相信我需要一个围绕Task.Delay的包装器,它将捕获异常并使其静音,但是否则会完全暴露Task.Delay的行为。我想在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();
}
答案 0 :(得分:6)
F#异步工作流具有内置的取消支持功能,因此使用这些工具而非使用任务可能会让您的生活更加轻松。您的问题并没有真正提供足够的信息来理解您要做的事情,但下面是使用async
来表示非常接近您的示例的示例:
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)
DoWork
函数将工作作为一项任务开始,可以很容易地从C#中使用。