gpt4 book ai didi

c# - 如何在 C# 中创建和使用自定义 Awaitable?

转载 作者:太空狗 更新时间:2023-10-30 00:20:12 27 4
gpt4 key购买 nike

我正在尝试实现自定义 awaiteable 以执行 await Thread.SleepAsync() 而无需创建任何其他线程。

这是我得到的:

    class AwaitableThread : INotifyCompletion
{
public AwaitableThread(long milliseconds)
{
var timer = new Timer(obj => { IsCompleted = true; }, null, milliseconds, Timeout.Infinite);
}

private bool isCompleted = false;

public bool IsCompleted
{
get { return isCompleted; }
set { isCompleted = value; }
}

public void GetResult()
{}

public AwaitableThread GetAwaiter() { return this; }

public void OnCompleted(Action continuation)
{
if (continuation != null)
{
continuation();
}
}
}

下面是 sleep 的工作原理:

    static async Task Sleep(int milliseconds)
{
await new AwaitableThread(milliseconds);
}

问题是这个函数立即返回,即使在 OnCompleted 中,IsCompleted 仍然是 false。

我做错了什么?

最佳答案

为生产使用完全实现可等待模式是一项棘手的工作——您需要捕获执行上下文等。 Stephen Toub's blog post对此有更多的细节。在许多情况下,搭载 Task<T> 更容易或 Task , 可能使用 TaskCompletionSource .例如,在您的情况下,您可以编写相当于 Task.Delay 的内容像这样:

public Task MyDelay(int milliseconds)
{
// There's only a generic TaskCompletionSource, but we don't really
// care about the result. Just use int as a reasonably cheap version.
var tcs = new TaskCompletionSource<int>();

Timer timer = new Timer(_ => tcs.SetResult(0), null, milliseconds,
Timeout.Infinite);
// Capture the timer variable so that the timer can't be garbage collected
// unless the task is (in which case it doesn't matter).
tcs.Task.ContinueWith(task => timer = null);

return tcs.Task;
}

您现在可以 await该任务,就像您可以等待 Task.Delay 的结果一样.

关于c# - 如何在 C# 中创建和使用自定义 Awaitable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13430266/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com