【发布时间】:2021-12-16 09:15:22
【问题描述】:
正如问题所说,我想知道如何创建内联异步任务。我尝试了以下方法(当然,T 这是一个通用抽象,你应该用你想要的任何对象替换它):
var task = new Task<T>(() => new T());
var taskResult = await task;
但是,当 taskResult 行被执行时,程序就会冻结 - 很可能是因为 Task 不是异步的。我知道我可以创建一个异步方法并对其执行等待,但由于我正在开发单元测试,我更喜欢内联任务定义。
那么,我的问题是:我将如何编写一个不会冻结程序的可等待内联任务?
编辑:背景是我正在使用 Moq 并且需要模拟一些 async Task(...) 方法。为了模拟这些,.Setup(...).Returns(...) 要求我返回一个任务。
我尝试使用上面的代码进行内联创建,以及单元测试方法之外的async Task<T> 方法。内联创建只是冻结了,而该方法运行得非常好。我得出的结论是,这两者之间唯一真正的区别是方法是异步的,而内联代码不是;因此为什么我认为失败“很可能是因为内联任务不是异步的”。
我试图四处寻找这个问题的答案,但除了new Task<T>(() => ...) 之外什么都没有看到。因此,我问了这个问题,以帮助将来可能遇到此问题的其他人。很抱歉一开始就让我的意图和问题不清楚。我希望这能澄清它!
【问题讨论】:
-
你也可以这样使用:
var taskResult = await Task.Run(() => new T());. -
你到底想在这里做什么?构造函数确实没有任何异步要做(构造函数本质上是同步的),所以:你为什么希望它是异步的?我很欣赏您可能正在简化,但是:细节真的很重要。老实说,显示的代码的正确版本是:
var result = new T();- 但是,Task.FromResult(new T())可能有用,注意异步和线程不是一回事。您是否尝试在另一个线程上运行构造函数?如果是这样:为什么? -
然后:
Task.FromResult(new T()) -
FWIW:我认为这里的负面回应是因为您提出了一个意图真的很不清楚的问题,然后立即发布了一个真的,对于那个不清楚的问题,真是奇怪的答案;如果你真的明确了你想要做什么,人们就会说“task.fromresult”,并且:我们都会继续我们的一天
-
这是XY Problem的情况。