等待同一任务的多个对象的 TaskCompletionSource
TaskCompletionSource for multiple objects awaiting same Task
我想知道在以下示例中使用 TaskCompletionSource
class 是否合适:
原始代码/没有 TaskCompletionSource
public async Task GetData()
{
if (!IsLoaded)
{
MyList = await Mediator.Send(new GetData());
IsLoaded = true;
}
}
此函数在我的 .NET Core Web 应用程序中作为单例范围服务的一部分提供。多个对象可以使用 MyList
中的记录,并且在使用列表之前将等待 GetData()
函数。
从示例函数可以看出,当第一次调用还在等待Mediator请求的结果时,该方法可能会被调用多次。我想要一个允许多个对象等待同一个任务的解决方案。那么为此目的使用 TaskCompletionSource
对象是否合适?
使用 TaskCompletionSource 重构
private TaskCompletionSource getDataTask;
public async Task VerifyDataIsLoaded()
{
if (getDataTask == null)
{
getDataTask = new TaskCompletionSource();
Task.Factory.StartNew(async () =>
{
await GetData();
getDataTask.TrySetResult();
}
}
return getDataTask.Task;
}
private async Task GetData()
{
MyList = await Mediator.Send(new GetData());
}
这应该导致第一次调用 VerifyDataIsLoaded()
实例化 TaskCompletionSource getDataTask
对象的实例,在新的线程任务中启动 GetData()
函数,并且 returning getDataTask.Task
属性.
现在,如果在 GetData()
函数等待来自 Mediator
对象的 return 时,任何其他对象调用 VerifyDataIsLoaded()
,它们都将等待同一个任务,并防止对 GetData
.
的任何冗余调用
想法?? ... 馊主意??更好的方法??
这个的正常模式是 Lazy<Task<T>>
,或者 custom AsyncLazy<T>
type。
private readonly Lazy<Task> getDataTask = new(GetData);
public Task VerifyDataIsLoadedAsync() => getDataTask.Value;
尽管总的来说,我不推荐这种异步初始化API,因为消费者始终记得对其进行初始化。我更喜欢异步工厂模式。
我想知道在以下示例中使用 TaskCompletionSource
class 是否合适:
原始代码/没有 TaskCompletionSource
public async Task GetData()
{
if (!IsLoaded)
{
MyList = await Mediator.Send(new GetData());
IsLoaded = true;
}
}
此函数在我的 .NET Core Web 应用程序中作为单例范围服务的一部分提供。多个对象可以使用 MyList
中的记录,并且在使用列表之前将等待 GetData()
函数。
从示例函数可以看出,当第一次调用还在等待Mediator请求的结果时,该方法可能会被调用多次。我想要一个允许多个对象等待同一个任务的解决方案。那么为此目的使用 TaskCompletionSource
对象是否合适?
使用 TaskCompletionSource 重构
private TaskCompletionSource getDataTask;
public async Task VerifyDataIsLoaded()
{
if (getDataTask == null)
{
getDataTask = new TaskCompletionSource();
Task.Factory.StartNew(async () =>
{
await GetData();
getDataTask.TrySetResult();
}
}
return getDataTask.Task;
}
private async Task GetData()
{
MyList = await Mediator.Send(new GetData());
}
这应该导致第一次调用 VerifyDataIsLoaded()
实例化 TaskCompletionSource getDataTask
对象的实例,在新的线程任务中启动 GetData()
函数,并且 returning getDataTask.Task
属性.
现在,如果在 GetData()
函数等待来自 Mediator
对象的 return 时,任何其他对象调用 VerifyDataIsLoaded()
,它们都将等待同一个任务,并防止对 GetData
.
想法?? ... 馊主意??更好的方法??
这个的正常模式是 Lazy<Task<T>>
,或者 custom AsyncLazy<T>
type。
private readonly Lazy<Task> getDataTask = new(GetData);
public Task VerifyDataIsLoadedAsync() => getDataTask.Value;
尽管总的来说,我不推荐这种异步初始化API,因为消费者始终记得对其进行初始化。我更喜欢异步工厂模式。