加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 顶级任务导致错误“当前的SynchronizationContext可能不会

发布时间:2020-12-16 01:59:44 所属栏目:百科 来源:网络整理
导读:参见英文答案 The current SynchronizationContext may not be used as a TaskScheduler????????????????????????????????????3个 我还没有看到答案,尽管我已经查看了stackoverflow和文档. 如果我调用从计时器处理程序或其他任务创建任务的代码,则此错误将在
参见英文答案 > The current SynchronizationContext may not be used as a TaskScheduler????????????????????????????????????3个
我还没有看到答案,尽管我已经查看了stackoverflow和文档.

如果我调用从计时器处理程序或其他任务创建任务的代码,则此错误将在下面的ContinueWidth上出现.例如,如果它被包装在另一个任务中,该任务每隔一个间隔(例如每1秒)创建一次任务,如下所示.我有高级别任务的唯一原因是每个间隔创建这些较低的任务.

//更高级别的任务创建

Task task = Task.Factory.StartNew(new Action(UpdateAllDuringInterval));

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;
    }

如果需要更多信息,请告诉我.随意给我这个代码的其他陷阱.谢谢!

解决方法

原因很简单但是解决方案可能需要您重新设计任务的一些交互.您没有设置SynchronizationContext(即SynchronizationContext.Current为null),因此无法从中创建TaskScheduler.一种选择是在UI线程上运行的地方调用TaskScheduler.FromCurrentSynchronizationContext(),然后向下传递到构造延续的方法.另一个是创建任务以传递它们,以便UI线程可以附加延续.

通常认为像_testMode这样的标志是代码气味,可能只是测试代码集.然后你有一些你没有真正测试的交互,因为测试代码做了一件事,但实际的应用程序做了另一件事.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读