是否有可以在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
答案 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()方法?