总而言之,我有一种情况,我被要求对一个大型的“成本计算”算法进行多线程处理。我对Task
s 比较有经验,并且有信心采用类似的模式
CancellationTokenSource cancelSource = new CancellationTokenSource();
CancellationToken token = cancelSource.Token;
TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task<bool> asyncTask = null;
asyncTask = Task.Factory.StartNew<bool>(() =>
SomeMethodAsync(uiScheduler, token, _dynamic), token);
asyncTask.ContinueWith(task =>
{
// For call back, exception handling etc.
}, uiScheduler);
然后对于我需要提供的任何操作和 UI 操作,我会使用
Task task = Task.Factory.StartNew(() =>
{
mainForm.progressLeftLabelText = _strProgressLabel;
}, CancellationToken.None,
TaskCreationOptions.None,
uiScheduler);
这可能包含在一个方法中。
现在,我意识到我可以让这一切变得不那么复杂,并利用async/await
.NET 4.5 的关键字。但是,我有一些问题:如果我有一个长期运行的方法可以使用
// Start processing asynchroniously.
IProgress<CostEngine.ProgressInfo> progressIndicator =
new Progress<CostEngine.ProgressInfo>();
cancelSource = new CancellationTokenSource();
CancellationToken token = cancelSource.Token;
CostEngine.ScriptProcessor script = new CostEngine.ScriptProcessor(this);
await script.ProcessScriptAsync(doc, progressIndicator, token);
哪里CostEngine.ProgressInfo
是一些用于返回进度信息的基本类,该方法ProcessScriptAsync
定义为
public async Task ProcessScriptAsync(SSGForm doc, IProgress<ProgressInfo> progressInfo,
CancellationToken token, bool bShowCompleted = true)
{
...
if (!await Task<bool>.Run(() => TheLongRunningProcess(doc)))
return
...
}
我有两个问题:
为了几乎
ProcessScriptAsync
立即将控制权返回给 UI ,我等待一个新的委托(这似乎避免了无休止的/ s链)。这是正确的打电话方式吗?['延迟初始化',通过包装外部方法?]Task<bool>
async
await
ProcessScriptAsync
要从内部访问 UI
TheLongRunningProcess
,我只需传入 UI 吗TaskScheduler
uiScheduler
?即TheLongRunningProcess(doc, uiScheduler)
,然后使用:
Task task = Task.Factory.StartNew(() =>
{
mainForm.progressLeftLabelText = _strProgressLabel;
}, CancellationToken.None,
TaskCreationOptions.None,
uiScheduler);
像之前一样?
对不起,长度和感谢您的时间。