我试图将两个独立函数的功能连接到一个Task中。我可能很迂腐,但我也很想知道这是否可能,所以希望有一些C#向导有答案。
这是当前的设置。
async Task GetData()
{
// Get some cached data immediately from the database
Data = FetchDataLocal();
// Replace the local data with the data from the web when it is available
Data = await FetchDataRemote();
}
我想将这两个函数移动到只返回Data
的单个任务中,但当然任务只能返回一次。
所以基本上我需要这种(下面)的功能,但形式正确。我很乐观,那里有一个优雅的解决方案。
async Task<DataType> GetData()
{
// Get some cached data immediately from the database
return FetchDataLocal();
// Replace the local data with the data from the web when it is available
return await FetchDataRemote();
}
是否有某种任务解决方案允许您执行此类操作?因此,任务将返回两次数据(即时数据,然后是延迟数据)。解决方案可能不是一个任务,但我不确定它会是什么。
答案 0 :(得分:2)
假设您正在使用MVVM应用程序,我建议使用my NotifyTask<T>
type,它会为您处理INotifyPropertyChanged
内容:
public NotifyTask<TData> Data;
ViewModelConstructor()
{
// Get some cached data immediately from the database
var immediateData = FetchDataLocal();
// Replace the local data with the data from the web when it is available
Data = NotifyTask.Create(FetchDataRemote(), immediateData);
}
如果您使用NotifyTask<T>
,那么您需要数据绑定到Data.Result
。
答案 1 :(得分:0)
您可以创建一个包含两个对象的自定义类,并在事件更新时发出事件。
public class DeferredData<T> : INotifyPropertyChanged
{
public DeferredData(T cachedData, Task<T> dataFactory)
{
_data = cachedData;
DatabaseLookupTask = dataFactory.ContinueWith(task => Data = task.Result, CancellationToken.None, TaskContinuationOptions.RunContinuationsAsynchronously,
TaskScheduler.FromCurrentSynchronizationContext());
}
private T _data;
public T Data
{
get { return _data; }
private set
{
if (Equals(value, _data)) return;
_data = value;
OnPropertyChanged();
}
}
public Task DatabaseLookupTask { get; }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
像
一样使用 DeferredData<DataType> GetData()
{
// Get some cached data immediately from the database
var localData = FetchDataLocal();
// Replace the local data with the data from the web when it is available
var remoteTask = FetchDataRemote();
return new DeferredData<DataType>(localData, remoteTask);
}