相当于F#StartImmediate

时间:2014-05-14 16:35:41

标签: c# f# async-await

是否有可以在StartImmediate执行的F#' s Task的C#等价物?我有时需要等待一个函数,但有时候我只是想让方法在不使用await的情况下回调到UI线程。

如果可能,我想避免异步无效。

示例:

public async void DoSomething()
{
    //before runs on UI thread
    await OtherThing();
    //after runs on UI thread
}

public async Task DoSomethingElse()
{
    //before runs on UI thread
    await OtherThing();
    //I want this to run on the UI thread
}

public void CallDoSomething()
{
    DoSomething(); //no need to await, returns to the UI thread to continue execution

    DoSomethingElse();//Doesn't return to the UI thread to continue execution

    DoSomethingElse().???(); // how to return to the UI thread for the async callback?
}

在F#中,这将是这样的:

let CallDoSomething () =

    //more code here

    async {
        //runs on the current thread
        do! OtherThing()
        //runs on the current thread
    } |> Async.StartImmediate

    //code here doesn't wait for the async to finish

2 个答案:

答案 0 :(得分:4)

所以,在查看代码示例时。您有async方法返回Task。您正在调用该方法,然后在生成的任务上调用Start(不调用await)。这将在运行时抛出异常。只需调用该方法即可启动该任务。启动已经运行的任务(或已完成的任务,如果它在返回之前完成)将抛出异常。您只能Start使用您未使用的Task构造函数创建的任务。

您还在评论中声明,在致电DoSomethingElse后返回时,您不在UI线程中。那是错误的。代码在UI线程中运行。

您还暗示await中的DoSomethingElse不会封送到UI线程的回调,但它。由于它是从UI线程调用的,因此它捕获了UI上下文,并在调用await时使用它。

简而言之,除了删除对Start的调用之外,您无需执行任何操作。

所遇到的一个问题,如果你构建这样的代码,那就是你永远不会知道你的代码是否错误,因为没有什么可以观察到任何异常。有两种方法可以解决这个问题。一个是你在这个庄园中调用的每个方法都认为自己是“顶级方法”并处理所有异常,而不是每个抛出任何异常。

另一种选择是存储以这种方式调用的所有任务和await Task.WhenAll这些任务,这样你就可以在完成任何错误时观察它们。

答案 1 :(得分:-2)

您是否尝试过Task类的RunSynchronously()方法?