您通常我会使用后台工作程序执行此操作,但我希望使用C#Task来执行此操作,只是为了更好地理解任务。
问题是我有一个具有以下属性的类
private int _number1;
public int Number1
{
get { return _number1; }
set { _number1 = value; OnPropertyChanged("Number1");}
}
private int _number2;
public int Number2
{
get { return _number2; }
set { _number2 = value; OnPropertyChanged("Number2");}
}
请注意,我使用的是INotifyPropertyChanged。
Number1 = Task<int>.Factory.StartNew(() => GenerateResult()).Result;
Number2 = Task<int>.Factory.StartNew(() => GenerateResult2()).Result;
GenerateResult和GenerateResult2只是dumme方法,他们会睡觉,然后返回一个数字。
我如何使这项工作异步?从现在开始,GenerateResult2()首先在GenerateResult()完成时调用。
我需要它能够工作Async,因为我不知道每个任务何时完成,或者即使它将完成。
答案 0 :(得分:13)
当您获得Result
属性时,您实际上正在等待任务完成。它将在后台线程上执行,但是在启动下一个线程之前,您正在主线程中等待完成。
有关详细信息,请参阅MSDN doc。
您应该可以从后台线程中分配属性:
Task<int>.Factory.StartNew(() => Number1 = GenerateResult());
WPF数据绑定将take care of marshalling PropertyChanged事件发送到正确的调度程序线程。
答案 1 :(得分:3)
我检查了这个:Task Parallelism (Task Parallel Library)并且它指出当使用System.Threading.Tasks.Task<TResult>
时,任务以异步方式运行并且可以按任何顺序完成。 如果在计算完成之前访问了Result,则该属性将阻止该线程,直到该值可用。
我认为这意味着如果您在获取值之前访问.Result
,就像您在示例代码中所做的那样,您将不得不等待它首先完成。
它确实有意义,因为在任务完成之前不会填充Result
属性。
答案 2 :(得分:-4)
Task<int>.Factory.StartNew(() => GenerateResult2()).ContinueWith(() => GenerateResult());