我正在使用XF pcl制作应用程序。即使我已经在商店推出了我的应用程序,我仍然是c#world的新手。我特别使用线程时遇到了麻烦。
在XF / iOS中,我在启动app后花了一段时间(超过一天),我的代码的所有Task.Run()都没有启动新线程。一个人告诉我,如果我有可能开始很多线程,不知何故他们没有被终止。所以新线程没有开始。
所以我搜索了我的项目,我的代码中有大约20个位置的Task.Run。
我在调用'async Task'方法时使用它,即使它不需要后台线程。
所以,我打算使用'async void'来改变它。但我已经这样改变了。没问题。
让我们说AAAAA()是我正在使用的一些nuget库的'异步任务'方法。所以 我无法改变方法。
void Something()
{
...
Task.Run(async () => await XXXXX.AAAAA());
...
}
async void Something()
{
...
await XXXXX.AAAAA();
...
}
但有时,我遇到了我无法轻易改变异步方法。所以我当时就会这样改变。
void Something()
{
...
AA();
...
}
async void AA()
{
await XXXXX.AAAAA();
}
除非没有后台线程,否则这样可以吗?
我问这个问题是因为我看了很多视频,说不要使用“Async void”。
我想知道如果没有问题我是否可以这样使用。
任何建议都会对我有所帮助。 感谢。
答案 0 :(得分:5)
不要执行async void
。关于它有几个worst practices。
相反,尝试通过良好的异步编程方法从根本位解决线程问题。
不要只是“开火而忘记”。期望您的任务结束并释放资源。有很好的理由不来做Task.Run(...)
并忘掉它。
异步方法存在是有原因的。它们返回Future
(引用Java世界)。如果你解雇过多的异步任务需要很长时间才能完成或陷入循环,你就会耗尽系统资源,最终可能无法产生新的任务。
所以分析你的问题,不要只是从随机包中运行随机方法。设计您的工作流程并识别并行性。
一个简单直接的解决方案是Task.Run(()=>).Wait()
。这会破坏各种并行性,但会限制资源,最重要的是,它会遵循同步编程。
虽然我不鼓励无限制/不受控制地使用线程,但事实是Task.Run(...)
不一定会产生新线程。在某些情况下,它实际上可能无法做任何事情。
例如,我被迫这样做以强制开始一个新线程
Task.Factory.StartNew(()=>..., cancellationToken: tokenSource.Token, creationOptions:
TaskCreationOptions.LongRunning, scheduler: TaskScheduler.Default);
TaskCreationOptions.LongRunning
告诉Task工厂使用可用的单独线程。通常,Task.Run
通过利用VM等待从其他任务运行代码来在同一当前线程上运行,以便执行轻量级上下文切换。如果同步代码以同步方式阻塞,则运行时可能无法控制其他任务。
一个是响应性。如果您的应用程序完全异步,那么充分利用TPL会使您的UI线程在等待时响应,例如:如果你点击一个按钮,你将看不到整个窗口变灰并“卡住”。 Microsoft已引入此行为,以帮助对正确的多线程编程不友好的开发人员
另一个是 I / O优化。如果你需要下载5个文件,从磁盘解析文本文件并在数据库中存储一堆行,你可以激活7个任务,利用每个任务的I / O等待时间(例如SSL握手,磁盘缓冲,SQL响应等待)这样,7个任务将在最长的时间内合理地完成。
如果您只是因为在NuGet库中找到异步方法而调用异步方法,那么您只是做错了,因为您可能需要调用相应的同步版本
您的问题表明对并行编程缺乏了解。事实上,你说你是C#的新手。欢迎来到.NET世界。
并行编程并不容易,如果不了解您的应用程序设计,就无法在一个简短的答案中帮助您。您需要通过发布真实或类似的实际代码,为应用程序的某些部分提供几个示例和/或询问有关特定最佳实践的问题。