すべて、大規模な 'Cost-Crunching' アルゴリズムをマルチスレッド化するように依頼された状況があります。私は比較的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);
whereCostEngine.ProgressInfo
は進捗情報を返すために使用されるいくつかの基本的なクラスであり、メソッドProcessScriptAsync
は次のように定義されています
public async Task ProcessScriptAsync(SSGForm doc, IProgress<ProgressInfo> progressInfo,
CancellationToken token, bool bShowCompleted = true)
{
...
if (!await Task<bool>.Run(() => TheLongRunningProcess(doc)))
return
...
}
2 つの質問があります。
ほとんどすぐに UI に制御を戻すために、新しいデリゲート
ProcessScriptAsync
を待機します (これにより、/の無限のチェーンを回避しているように見えます)。この呼び方は正しいですか?[「遅延初期化」、外側のメソッドでラップすることによって?]Task<bool>
async
await
ProcessScriptAsync
内から UI にアクセスするには、UI を
TheLongRunningProcess
渡すだけですかTaskScheduler
uiScheduler
。つまりTheLongRunningProcess(doc, uiScheduler)
、次を使用します。
Task task = Task.Factory.StartNew(() =>
{
mainForm.progressLeftLabelText = _strProgressLabel;
}, CancellationToken.None,
TaskCreationOptions.None,
uiScheduler);
従来通り?
長々と申し訳ありませんが、お時間をいただきありがとうございます。