c# await 异步编程工具类

public static class TaskCompletionSourceManager
{
    private static Dictionary<string, TaskCompletionSource<object>> webTcsList = new();
    private static readonly object webTcsListLocker = new object();

    public static string CreateTaskCompletionSource()
    {
        // 使用泛型TaskCompletionSource并指定异步延续选项
        var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
        var id = Guid.NewGuid().ToString();

        lock (webTcsListLocker)
        {
            webTcsList.Add(id, tcs);
        }
        return id;
    }

    public static void CancelTaskCompletionSource(string tcsId)
    {
        lock (webTcsListLocker)
        {
            if (!webTcsList.TryGetValue(tcsId, out var tcs))
                return;

            if (tcs.TrySetCanceled())
                webTcsList.Remove(tcsId);
        }
    }

    public static void CompleteTaskCompletionSource(string tcsId)
    {
        lock (webTcsListLocker)
        {
            if (!webTcsList.TryGetValue(tcsId, out var tcs))
                return;

            if (tcs.TrySetResult(null)) // 设置结果为null
                webTcsList.Remove(tcsId);
        }
    }

    public static async Task WaitTaskCompletionSource(string tcsId, TimeSpan timeout)
    {
        Task taskToWait = null;

        lock (webTcsListLocker)
        {
            if (webTcsList.TryGetValue(tcsId, out var tcs))
            {
                taskToWait = tcs.Task;
            }
        }

        if (taskToWait == null)
            return;

        using (var timeoutCancellationTokenSource = new CancellationTokenSource())
        {
            if (timeout.TotalMilliseconds == 0)
            {
                await taskToWait;
                return;
            }

            var timeoutTask = Task.Delay(timeout, timeoutCancellationTokenSource.Token);
            var completedTask = await Task.WhenAny(taskToWait, timeoutTask).ConfigureAwait(false);

            if (completedTask == timeoutTask)
            {
                throw new TimeoutException($"WaitTaskCompletionSource 操作超时,时间:{timeout.TotalSeconds}秒");
            }
            else
            {
                timeoutCancellationTokenSource.Cancel();
                await taskToWait.ConfigureAwait(false);
            }
        }
    }
}

 

posted on 2026-01-22 21:03  空明流光  阅读(0)  评论(0)    收藏  举报

导航