C# 是否只有在以下情况下才有办法启动任务;等待“;发生?

C# 是否只有在以下情况下才有办法启动任务;等待“;发生?,c#,.net,async-await,C#,.net,Async Await,考虑到: 只有返回void、Task或Task的方法才能标记为异步 如果我只需要在任务被“等待”时调用逻辑或启动某些内容,在这种情况下,当TaskAwaiter实现的方法OnCompleted(Action continuation)或UnsafeOnCompleted(Action continuation)时,我能以某种方式完成吗 例如: 我需要模拟一些返回任务的实现,在这种情况下,我的模拟需要在一个线程中使用和继续,但不能操作同步上下文 我知道这是一个非常具体的场景,但只是理论上的。同样还

考虑到:

只有返回void、Task或Task的方法才能标记为异步

如果我只需要在任务被“等待”时调用逻辑或启动某些内容,在这种情况下,当
TaskAwaiter
实现的方法
OnCompleted(Action continuation)
UnsafeOnCompleted(Action continuation)
时,我能以某种方式完成吗

例如:

我需要模拟一些返回
任务
的实现,在这种情况下,我的模拟需要在一个
线程
中使用和继续,但不能操作
同步上下文

我知道这是一个非常具体的场景,但只是理论上的。同样还有
Unwrap()
方法,是否有类似
Wrap(IAwaitable accesswaiter)
的方法


如果
任务
仅在
等待
被“等待”时启动,那么它已经解决了我的问题。谢谢您的帮助。

不。但是如果您真的需要,您可以编写自己的等待程序进行模拟。

不。但是如果您真的需要,您可以编写自己的等待程序进行模拟。

我不建议您这样做,但是您可以在等待发生时启动
任务

下面是一个玩具示例,我不建议再次使用:

用法:

await TimeSpan.FromSeconds(3);
类似于
foreach
循环如何扩展为调用可枚举项上的
GetEnumerator()
的代码,
await
是一个表达式,它扩展为调用
().GetAwaiter()
的内容,并使用一系列其他魔法来实现连续性

编辑 如果您只想等待可能尚未启动的
任务
,请在尚未启动时启动它,您可以简单地使用以下方法:

public static Task EnsureStarted(this Task task)
{
    if (task.Status == TaskStatus.Created)
    {
        try
        {
            task.Start();
        }
        catch (InvalidOperationException) { }
    }
    return task;
}
这样使用:

await task.EnsureStarted();

我不建议您这样做,但您可以在等待发生时启动
任务

下面是一个玩具示例,我不建议再次使用:

用法:

await TimeSpan.FromSeconds(3);
类似于
foreach
循环如何扩展为调用可枚举项上的
GetEnumerator()
的代码,
await
是一个表达式,它扩展为调用
().GetAwaiter()
的内容,并使用一系列其他魔法来实现连续性

编辑 如果您只想等待可能尚未启动的
任务
,请在尚未启动时启动它,您可以简单地使用以下方法:

public static Task EnsureStarted(this Task task)
{
    if (task.Status == TaskStatus.Created)
    {
        try
        {
            task.Start();
        }
        catch (InvalidOperationException) { }
    }
    return task;
}
这样使用:

await task.EnsureStarted();

你到底想解决什么问题?您的“mock”示例没有意义,因为异步mock不需要在特定线程中完成任务,我看到了
ToAsyncEnumerable
的实现,每次使用
MoveNext
时,都会使用
task.Factory.StartNew
创建一个新任务。所以,我想使用我自己的“等待者”,但显然我不能这样做,因为这会改变界面。我所能做的最多就是创建一个自定义的
toasynumerable
实现,用于
TaskFactory
或类似的东西。还有其他建议吗?那么您是在单元测试中试图避免
StartNew
?您可以编写自己的扩展方法和实现。不过,我不确定是否值得对单元测试进行微观优化。事实上,我的单元测试只是出于理论目的,但我真的会尝试一些不同的方法,编写自己的扩展方法(在本例中用于实际场景)。谢谢你的帮助,我还是很困惑如果我能更好地理解用例,我觉得有更好的解决方案。你想解决的问题到底是什么?您的“mock”示例没有意义,因为异步mock不需要在特定线程中完成任务,我看到了
ToAsyncEnumerable
的实现,每次使用
MoveNext
时,都会使用
task.Factory.StartNew
创建一个新任务。所以,我想使用我自己的“等待者”,但显然我不能这样做,因为这会改变界面。我所能做的最多就是创建一个自定义的
toasynumerable
实现,用于
TaskFactory
或类似的东西。还有其他建议吗?那么您是在单元测试中试图避免
StartNew
?您可以编写自己的扩展方法和实现。不过,我不确定是否值得对单元测试进行微观优化。事实上,我的单元测试只是出于理论目的,但我真的会尝试一些不同的方法,编写自己的扩展方法(在本例中用于实际场景)。谢谢你的帮助,我还是很困惑我觉得如果我能更好地理解用例,会有更好的解决方案。是的,很酷,我真的可以用它来处理
任务的开始,但在我的情况下,该方法需要返回
任务
,所以当“wait”发生时,我不能返回与使用自定义getwaiter方法不同的东西。是的,对于大多数场景来说都能很好地工作,但听起来像是“黑客”,每个返回
任务
的方法我都需要调用这个扩展。主要目标是封装行为,而不是影响谁将使用。这给了我一些想法,如果我实施一个“跳蹦床”的概念,也许我会以另一种方式达到我的目标。谢谢是的,很酷,我真的可以用这个来处理
任务的开始,但是在我的例子中,这个方法需要返回一个
任务
,所以当“等待”发生时,我不能返回一些与使用自定义GetAwaiter方法不同的东西。是的,对于大多数场景来说都可以很好地工作,但听起来像是“黑客”