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);