C# 异步并等待,不带;线程;?我可以定制引擎盖下发生的事情吗?
我有一个问题,关于C#4.5中新的C# 异步并等待,不带;线程;?我可以定制引擎盖下发生的事情吗?,c#,async-await,C#,Async Await,我有一个问题,关于C#4.5中新的async/wait关键字和Task类的可定制性如何 首先,了解我的问题的一些背景:我正在开发一个具有以下设计的框架: 一个线程有一个“当前要做的事情”(通常大约100到200项)的列表,这些事情作为自己的数据结构存储并作为列表保存。它有一个Update()函数,用于枚举列表,并查看是否需要执行某些“东西”,然后执行。基本上它就像一个大线程调度程序。为了简化事情,让我们假设“要做的事情”是当它们“完成”(并且不应称为下一次更新)时返回布尔值true,当调度程序
async
/wait
关键字和Task
类的可定制性如何
首先,了解我的问题的一些背景:我正在开发一个具有以下设计的框架:
- 一个线程有一个“当前要做的事情”(通常大约100到200项)的列表,这些事情作为自己的数据结构存储并作为列表保存。它有一个
函数,用于枚举列表,并查看是否需要执行某些“东西”,然后执行。基本上它就像一个大线程调度程序。为了简化事情,让我们假设“要做的事情”是当它们“完成”(并且不应称为下一次更新)时返回布尔值Update()
,当调度程序应在下一次更新时返回布尔值true
false
- 所有“东西”不能同时运行,也必须在这一个线程中运行(因为线程静态变量)
- 还有其他线程做其他事情。它们的结构是相同的:大循环在一个大的
-函数中迭代数百件事情Update()
- 线程可以互相发送消息,包括“远程过程调用”。对于这些远程调用,RPC系统将某种未来对象返回到结果值。在另一个线程中,插入一个新的“要做的事情”
- 一个常见的“事情”是将RPC序列链接在一起。目前,这种“链接”的语法非常冗长和复杂,因为您必须手动检查以前的RPC的完成状态,并调用下一个RPC等等
未来f1、f2;
bool SomeThingToDo()//在“完成”时返回true
{
如果(f1==null)
f1=Remote1.CallF1();
else if(f1.IsComplete&&f2==null)
f2=Remote2.CallF2();
else if(f2!=null&&f2.IsComplete)
返回true;
返回false;
}
现在,这一切听起来都像是C#5.0的async
和wait
可以帮助我。我还没有100%完全理解它在引擎盖下的作用(有什么好的参考资料吗?),但我从我看过的一些谈话中了解到,它通过这个非常简单的代码实现了我想要的:
async Task SomeThingToDo()//返回的任务在完成时完成。
{
等待Remote1.CallF1();
等待Remote2.CallF2();
}
但是我找不到一种方法来编写我的Update()
函数来实现类似的事情async
和await
似乎想使用任务
-类,而该类又似乎需要真正的线程
我迄今为止最接近的“解决方案”:
第一个线程(正在运行SomeThingToDo
)只调用它们的函数一次,并存储返回的任务,并在每次Update()
上测试任务是否完成
Remote1.CallF1
返回一个新任务,其中构造函数参数为空操作,并记住返回的任务。当F1实际完成时,它对任务调用RunSynchronously()
,将其标记为已完成
在我看来,这似乎是对任务系统的一种扭曲。此外,它在两个线程之间创建共享内存(任务的IsComplete
boolean),如果可能的话,我想用我们的远程消息交换系统来替换
最后,它不能解决我的问题,因为它不能与上面的wait-likeSomeThingToDo
实现一起工作。异步函数返回的自动生成的任务对象似乎立即完成了
最后,我的问题是:
任务
任务
而不使用任何与“阻塞”和“线程”相关的内容吗async
和wait
时会发生什么任务
表示将来某个时候可以完成的任务,可能会有结果。它有时是另一个线程中某些计算的结果,但不一定是。它可以是未来某个时刻发生的任何事情。例如,它可能是IO操作的结果
Remote1.CallF1
返回一个新任务,其中构造函数参数为空操作,并记住返回的任务。当F1实际完成时,它对任务调用RunSynchronously()
,将其标记为已完成
因此,这里缺少的是TaskCompletionSource
类。有了那块缺失的拼图,很多东西都应该放进去。您可以创建TCS对象,将Task
属性中的Task
传递给…任何人,然后使用SetResult
属性发出完成信号。这样做不会导致创建任何附加线程,也不会使用线程池
请注意,如果您没有结果,只需要一个任务
而不是任务
,那么只需使用TaskCompletionSource
或类似的内容,然后使用SetResult(false)
或任何合适的内容。通过将任务
强制转换为任务
,您可以对公共AP隐藏该实现