C# 异步并等待,不带;线程;?我可以定制引擎盖下发生的事情吗?

C# 异步并等待,不带;线程;?我可以定制引擎盖下发生的事情吗?,c#,async-await,C#,Async Await,我有一个问题,关于C#4.5中新的async/wait关键字和Task类的可定制性如何 首先,了解我的问题的一些背景:我正在开发一个具有以下设计的框架: 一个线程有一个“当前要做的事情”(通常大约100到200项)的列表,这些事情作为自己的数据结构存储并作为列表保存。它有一个Update()函数,用于枚举列表,并查看是否需要执行某些“东西”,然后执行。基本上它就像一个大线程调度程序。为了简化事情,让我们假设“要做的事情”是当它们“完成”(并且不应称为下一次更新)时返回布尔值true,当调度程序

我有一个问题,关于C#4.5中新的
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-like
SomeThingToDo
实现一起工作。异步函数返回的自动生成的任务对象似乎立即完成了

最后,我的问题是:

  • 我是否可以挂接到async/await以使用自己的实现而不是
    任务
  • 如果不可能,我可以使用
    任务
    而不使用任何与“阻塞”和“线程”相关的内容吗
  • 有什么好的参考资料吗?当我写
    async
    wait
    时会发生什么
  • 我可以挂接到async/await以使用自己的实现而不是任务吗

    如果这是不可能的,我可以在没有任何与“阻塞”和“线程”相关的情况下使用Task吗

    有什么好的参考吗?当我写async并等待时会发生什么

    我劝你不要问是/否问题。你可能不只是想要是/否的答案

    async和await似乎想使用任务类,而任务类又似乎需要真正的线程

    不,那不是真的。
    任务
    表示将来某个时候可以完成的任务,可能会有结果。它有时是另一个线程中某些计算的结果,但不一定是。它可以是未来某个时刻发生的任何事情。例如,它可能是IO操作的结果

    Remote1.CallF1
    返回一个新任务,其中构造函数参数为空操作,并记住返回的任务。当F1实际完成时,它对任务调用
    RunSynchronously()
    ,将其标记为已完成

    因此,这里缺少的是
    TaskCompletionSource
    类。有了那块缺失的拼图,很多东西都应该放进去。您可以创建TCS对象,将
    Task
    属性中的
    Task
    传递给…任何人,然后使用
    SetResult
    属性发出完成信号。这样做不会导致创建任何附加线程,也不会使用线程池

    请注意,如果您没有结果,只需要一个
    任务
    而不是
    任务
    ,那么只需使用
    TaskCompletionSource
    或类似的内容,然后使用
    SetResult(false)
    或任何合适的内容。通过将
    任务
    强制转换为
    任务
    ,您可以对公共AP隐藏该实现