Buc*_*uck 3 c# wpf multithreading task
我还没有看到答案,尽管我已经查看了stackoverflow和文档.
如果我调用从计时器处理程序或其他任务创建任务的代码,则此错误将在下面的ContinueWidth上出现.例如,如果它被包装在另一个任务中,每个间隔(例如每1秒)创建一个任务,如下所示.我有高级别任务的唯一原因是每个间隔创建这些较低的任务.
//更高级别的任务创建
...
Task task = Task.Factory.StartNew(new Action(UpdateAllDuringInterval));
Run Code Online (Sandbox Code Playgroud)
...
private void UpdateAllDuringInterval()
{
Stopwatch stopWatch = new Stopwatch();
do
{
// Start the stopwatch
stopWatch.Start();
// Create tasks
List<Task> tasks = CreateTasksAndStart();
// Wait for the tasks to complete if testing, since want to check results
if (this._testMode)
{
Task[] taskArray = tasks.ToArray();
Task.WaitAll(taskArray);
}
if (!_testMode)
{
// Get remaining time to complete interval and sleep for that time
int remainingTimeInMilliseconds = this._pollingIntervalInMilliseconds -
(int) stopWatch.Elapsed.TotalMilliseconds;
// truncating milliseconds
if (remainingTimeInMilliseconds > 0)
Thread.Sleep(remainingTimeInMilliseconds);
// will give time to CPU. Note that using Sleep used to be frowned upon but no longer due to advantages in multitasksing/CPU utilization
}
} while (!_testMode); // continue updating stocks once per interval if not testing
}
private List<Task> CreateTasksAndStart()
{
var tasks = new List<Task>();
lock (syncLock)
{
for (int i = 0; i < _stocksToUpdate.Count; i++)
{
var item = _stocksToUpdate[i];
var initialTask = Task.Factory.StartNew(() =>
{
GetUpdatedStockInformation(item);
});
var continuationTask = initialTask.ContinueWith((antecendent) =>
{
UpdateUIWithUpdatedStockInformation();
}
, CancellationToken.None, TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.FromCurrentSynchronizationContext());
// For testing, we want to wait on the continuation task to make sure updates are done
tasks.Add(continuationTask);
}
}
return tasks;
}
Run Code Online (Sandbox Code Playgroud)
如果需要更多信息,请告诉我.随意给我这个代码的其他陷阱.谢谢!
原因很简单但是解决方案可能需要您重新设计任务的某些交互.您没有SynchronizationContext集合(即为SynchronizationContext.Current空),因此TaskScheduler无法从中创建.一种选择是调用TaskScheduler.FromCurrentSynchronizationContext()在UI线程上运行的位置,然后向下传递到构造延续的方法.另一个是创建任务以传递它们,以便UI线程可以附加延续.
它通常被认为是代码气味,有这样的标志_testMode,大概只有测试代码集.然后你有一些你没有真正测试的交互,因为测试代码做了一件事,但实际的应用程序做了另一件事.
| 归档时间: |
|
| 查看次数: |
6052 次 |
| 最近记录: |