编写一个等待bool的异步方法

时间:2022-07-03 20:58:57

I would like to write a method that will await for a variable to be set to true.

我想编写一个等待变量设置为true的方法。

Here is the psudo code.

这是psudo代码。

bool IsSomethingLoading = false
SomeData TheData;

public async Task<SomeData> GetTheData()
{
   await IsSomethingLoading == true;
   return TheData;
}

TheData will be set by a Prism Event along with the IsSomethingLoading variable.

TheData将由Prism事件和IsSomethingLoading变量设置。

I have a call to the GetTheData method, but I would like it to run async (right now it just returns null if the data is not ready. (That leads to other problems.)

我有一个GetTheData方法的调用,但我希望它运行异步(现在它只是在数据没有准备好时返回null。(这会导致其他问题。)

Is there a way to do this?

有没有办法做到这一点?

2 个解决方案

#1


13  

In many situations like this what you need is a TaskCompletionSource.

在许多情况下,你需要的是TaskCompletionSource。

You likely have a method that is able to generate the data at some point in time, but it doesn't use a task to do it. Perhaps there is a method that takes a callback which provides the result, or an event that is fired to indicate that there is a result, or simply code using a Thread or ThreadPool that you are not inclined to re-factor into using Task.Run.

您可能有一种方法能够在某个时间点生成数据,但它不会使用任务来执行此操作。也许有一个方法接受一个提供结果的回调,或一个被触发的事件来指示结果,或者只是使用一个你不想重新考虑使用Task.Run的Thread或ThreadPool的代码。

public Task<SomeData> GetTheData()
{
    TaskCompletionSource<SomeData> tcs = new TaskCompletionSource<SomeData>();
    SomeObject worker = new SomeObject();
    worker.WorkCompleted += result => tcs.SetResult(result);
    worker.DoWork();
    return tcs.Task;
}

While you may need/want to provide the TaskCompletionSource to the worker, or some other class, or in some other way expose it to a broader scope, I've found it's often not needed, even though it's a very powerful option when it's appropriate.

虽然您可能需要/想要将TaskCompletionSource提供给worker或其他类,或者以某种其他方式将其暴露给更广泛的范围,但我发现它通常不需要,即使它在适当的时候是一个非常强大的选项。

It's also possible that you can use Task.FromAsync to create a task based on an asynchronous operation and then either return that task directly, or await it in your code.

您也可以使用Task.FromAsync基于异步操作创建任务,然后直接返回该任务,或者在代码中等待它。

#2


9  

You could use a TaskCompletionSource as your signal, and await that:

您可以使用TaskCompletionSource作为您的信号,并等待:

TaskCompletionSource<bool> IsSomethingLoading = new TaskCompletionSource<bool>();
SomeData TheData;

public async Task<SomeData> GetTheData()
{
   await IsSomethingLoading.Task;
   return TheData;
}

And in your Prism event do:

在你的Prism事件中:

IsSomethingLoading.SetResult(true);

#1


13  

In many situations like this what you need is a TaskCompletionSource.

在许多情况下,你需要的是TaskCompletionSource。

You likely have a method that is able to generate the data at some point in time, but it doesn't use a task to do it. Perhaps there is a method that takes a callback which provides the result, or an event that is fired to indicate that there is a result, or simply code using a Thread or ThreadPool that you are not inclined to re-factor into using Task.Run.

您可能有一种方法能够在某个时间点生成数据,但它不会使用任务来执行此操作。也许有一个方法接受一个提供结果的回调,或一个被触发的事件来指示结果,或者只是使用一个你不想重新考虑使用Task.Run的Thread或ThreadPool的代码。

public Task<SomeData> GetTheData()
{
    TaskCompletionSource<SomeData> tcs = new TaskCompletionSource<SomeData>();
    SomeObject worker = new SomeObject();
    worker.WorkCompleted += result => tcs.SetResult(result);
    worker.DoWork();
    return tcs.Task;
}

While you may need/want to provide the TaskCompletionSource to the worker, or some other class, or in some other way expose it to a broader scope, I've found it's often not needed, even though it's a very powerful option when it's appropriate.

虽然您可能需要/想要将TaskCompletionSource提供给worker或其他类,或者以某种其他方式将其暴露给更广泛的范围,但我发现它通常不需要,即使它在适当的时候是一个非常强大的选项。

It's also possible that you can use Task.FromAsync to create a task based on an asynchronous operation and then either return that task directly, or await it in your code.

您也可以使用Task.FromAsync基于异步操作创建任务,然后直接返回该任务,或者在代码中等待它。

#2


9  

You could use a TaskCompletionSource as your signal, and await that:

您可以使用TaskCompletionSource作为您的信号,并等待:

TaskCompletionSource<bool> IsSomethingLoading = new TaskCompletionSource<bool>();
SomeData TheData;

public async Task<SomeData> GetTheData()
{
   await IsSomethingLoading.Task;
   return TheData;
}

And in your Prism event do:

在你的Prism事件中:

IsSomethingLoading.SetResult(true);