WPF Async Task locking UI

烈酒焚心 提交于 2019-12-25 01:18:48

问题


I know I'm missing something stupid, the "StartProcess" Method is making the UI unresponsive and no amount of googling and tutorials has led me to an answer.

Here is my code:

    public MainWindow()
    {
        InitializeComponent();
        txtBlock.Text = "Testing";
        Initialize();
    }

    public void Initialize()
    {
        uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

        StartProcess();
    }

    async void StartProcess()
    {
         Task<int> result = Task.Factory.StartNew(() =>
        {
            txtBlock.Text += ("\n starting updater");
            while (true)
            {
                Thread.Sleep(3000);
            }
            return 0;
        }, CancellationToken.None, TaskCreationOptions.LongRunning, uiScheduler);
    }

Some background: I'm building an app that has to poll the DB every 5mins and update the UI with a to-do list for the user, hence the while(true) loop. The app has to poll the DB continuously throughout its lifetime.


回答1:


Well, you asked the TPL to invoke the Func in UI thread, it obeys your words.

In StartNew you pass uiScheduler as TaskScheduler, so the task will be queued to Dispatcher which will be invoked by UI thread.

If you don't want to execute in UI thread then use TaskScheduler.Default, doing so you can't update txtBlock.Text inside the Func. You need to marshal the call to UI thread or just set the txtBlock.Text outside the Func before StartNew.

Always prefer Task.Run if you're in .Net 4.5, be aware that StartNew is dangerous.

Couple of things to note:

  • Note that you're not leveraging the async feature at all. Without an await keyword method is not at all async. You don't need the async keyword at all(Infact you'll get a compiler warning, please pay attention to what compiler says).
  • Avoid async void methods(Except in event handlers), always use async Task if you don't need any return value, so that you could await it in the caller or attach continuation and so forth.

Update to add some code:

async Task StartProcess()
{
    while (true)
    {
        var result = await Task.Run(()=> MethodWhichCallsDBAndReturnsSomething());
        txtBlock.Text = result.ToString();//Use result and update UI
        await Task.Delay(5 * 60 * 1000);//await 5 mins
    }
}


来源:https://stackoverflow.com/questions/25769078/wpf-async-task-locking-ui

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!