Yit*_*tuo 8 c# multithreading asynchronous
我在网上搜索,但有关的信息很少 ThreadHelper.JoinableTaskFactory.RunAsync
如果我有以下代码,请Test1运行MainThread:
public bool Test1()
{
// Do something here
ThreadHelper.JoinableTaskFactory.RunAsync(this.Test2);
// Do something else
return false;
}
private async Task Test2()
{
await TaskScheduler.Default;
// do something here
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
// do something here
}
Run Code Online (Sandbox Code Playgroud)
如果RunAsync从未等待过可以吗?如果Test1在Test2运行完成之前返回会发生什么?
如果从未等待过 RunAsync 是否可以?
那要看。从JoinableTaskFactory的角度来看是可以的。所有必要的延续都将继续——只是你的调用方法不会等待它完成,如果你选择这样做,这就是不等待它的全部意义。
但总的来说,它可能对您的应用程序不利。考虑您的异步工作正在保存文件(或通过网络传输某些内容)并且用户关闭您的应用程序的情况。您不想让应用程序在关闭之前等待它完成吗?正如@GrzegorzSmulko 在他的回答中所说,它JoinableTaskFactory规定了一种在关闭(或处理您的对象)时阻塞的模式,以确保异步工作完成。
如果您在托管 CLR 并在退出前关闭它的应用程序中,还有另一个原因需要跟踪您的异步工作:您不希望托管线程在 AppDomain 最终确定时到处乱跑,否则您会发现您的应用程序在关机时崩溃。不过,当您拥有纯托管应用程序时,这不是问题,因为它只是退出而不关闭 CLR。它不会崩溃,但它仍然会放弃任何完成一半的工作。
在您使用的任何应用程序中,上述所有内容均JoinableTaskFactory适用。如果您碰巧在 Visual Studio 中使用它(我在这里一般是为更广泛的受众发言...我知道您的问题特别提到了 VS),那么规则的压力更大。您应该按照该部分的规定跟踪所有异步工作。你不应该有任何“一劳永逸”的工作。
该FileAndForget扩展方法实际上是用于微软内部使用,因为它发送错误,我们的遥测服务器。如果你真的只想忘记东西,你可以使用.Forget()扩展方法。但请记住,您应该只在使用AsyncPackage.JoinableTaskFactory实例或另一个跟踪您的异步工作以进行处理的实例安排工作后才使用它。不要使用它,ThreadHelper.JoinableTaskFactory因为它不会跟踪异步和遗忘的工作。例如,不要这样做:
ThreadHelper.JoinableTaskFactory.RunAsync(async () => { /* something async */ }).Forget();
Run Code Online (Sandbox Code Playgroud)
上面的问题是不会跟踪异步工作,因此不会阻止关闭。你应该这样做:
myAsyncPackage.JoinableTaskFactory.RunAsync(async () => { /* something async */ }).Forget();
Run Code Online (Sandbox Code Playgroud)
或者甚至更好:只需等待调用,在这种情况下,您几乎可以使用任何 JTF 实例:
await ThreadHelper.JoinableTaskFactory.RunAsync(async () => { /* something async */ });
Run Code Online (Sandbox Code Playgroud)
但是,如果您处于可以使用await的上下文中,则通常根本不需要JoinableTaskFactory.RunAsync,因为如果您可以只 await 委托本身中的代码。一些不常见的情况可能需要您仍然JoinableTaskCollection使用您可能想要使用的地方跟踪异步工作,await someJtf.RunAsync但通常您可以放弃 JTF 使用,在那里您可以自然地等待您的工作。