冻结界面的任务

时间:2017-09-04 19:53:19

标签: c# task

我正在使用3个任务同时执行3个任务,但是,当启动所有任务时,没有冻结GUI,它只会有点慢...当它返回上一个任务的结果时它完全冻结并停止更新GUI ...

async Task UpdateBlockChain()
        {
            var task = Task.Factory.StartNew((Action) =>
            {
                while (true)
                {
                    BlockChain blockChain = new BlockChain();
                    coinList[0].Price = blockChain.GetDataByNode("last");
                    coinList[0].Low = blockChain.GetDataByNode("low");
                    coinList[0].High = blockChain.GetDataByNode("high");
                    RefreshView();
                    Task.Delay(1000);
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());

            await Task.Delay(500);
        }

        async Task UpdateBitFinex()
        {
            var task = Task.Factory.StartNew((Action) =>
            {
                while (true)
                {
                    Bitfinex bitFinex = new Bitfinex();
                    coinList[1].Price = bitFinex.GetDataByNode("last_price");
                    coinList[1].Low = bitFinex.GetDataByNode("low");
                    coinList[1].High = bitFinex.GetDataByNode("high");
                    RefreshView();
                    Task.Delay(2000);
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());

            await Task.Delay(500);
        }

        async Task UpdateBitstamp()
        {
            var task = Task.Factory.StartNew((Action) =>
            {
                while (true)
                {
                    Bitstamp bitstamp = new Bitstamp();
                    coinList[2].Price = bitstamp.GetDataByNode("last");
                    coinList[2].Low = bitstamp.GetDataByNode("low");
                    coinList[2].High = bitstamp.GetDataByNode("high");
                    RefreshView();
                    Task.Delay(1000);
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());

            await Task.Delay(500);
        }

刷新视图:

void RefreshView()
        {
            if (dataGridView1.InvokeRequired)
            {
                dataGridView1.BeginInvoke(new Action(() =>
                {
                    dataGridView1.Update();
                    dataGridView1.Refresh();
                }));
            }
        }

运行任务:

await UpdateBlockChain();
await UpdateBitFinex();
await UpdateBitstamp();

以下是课程https://pastebin.com/DuQybhcz

的示例

我不知道我使用的方法是错误的,我为代码流错误道歉。

1 个答案:

答案 0 :(得分:0)

这是因为您使用TaskScheduler.FromCurrentSynchronizationContext,它应该安排任务在与调用的线程相同的线程上运行,在您的情况下是UI线程。

将所有工作卸载到后台线程,并且只使用BeginInvoke

将ui刷新操作封送到UI线程

另外,您必须在await Task.Delay(xxx)循环中调用while,否则循环之间没有延迟,并且它们非常占用CPU,并且安排了太多的UI更新

TaskScheduler

上引用MSDN
  

您可以使用TaskScheduler.FromCurrentSynchronizationContext方法   指定应该安排任务在特定的上运行   线。这在Windows窗体和Windows等框架中很有用   Presentation Foundation,用户界面对象的访问权限   通常限于在同一个线程上运行的代码   UI对象已创建。有关更多信息,请参见如何:计划   使用用户界面(UI)线程。

     

以下示例使用   Windows中的TaskScheduler.FromCurrentSynchronizationContext方法   Presentation Foundation(WPF)应用程序,用于安排相同的任务   创建用户界面(UI)控件的线程。