简体   繁体   English

后台任务正在阻塞 wpf .net 核心应用程序中的主线程

[英]background task is blocking main thread in wpf .net core application

I have a background task in my software which should run indefinitely.我的软件中有一个后台任务,应该无限期运行。

The code repeating the task (and possibly other tasks in the future) looks like this:重复该任务(以及将来可能还有其他任务)的代码如下所示:

public class RunTicketTasks
{
    public async Task RunBackgroundTasks()
    {
        AssignTickets assignTickets = new AssignTickets();
        while (true)
        {
            await assignTickets.AssignTicketCreator();
            await Task.Delay(5 * 60 * 1000);
        }
    }
}

At the same time I have the WPF UI MainWindow.xaml which is the application entry point as far as I know.同时我有 WPF UI MainWindow.xaml据我所知,这是应用程序入口点。

within public MainWindow I start the task like the following way:public MainWindow中,我按以下方式启动任务:

public MainWindow()
{ 
    InitializeComponent();
    JiraBackgroundTasks.RunTicketTasks ticketTasks = new JiraBackgroundTasks.RunTicketTasks();
    ticketTasks.RunBackgroundTasks();
}

Apparently, this starts the task on the same thread (I believe).显然,这会在同一个线程上启动任务(我相信)。 The task is started and running successfully, but the UI is beeing blocked due to long running operations.任务已启动并成功运行,但由于长时间运行操作,UI 被阻塞。 Meanwhile, when I uncomment the last line ticketTasks.RunBackgroundTasks();同时,当我取消注释最后一行ticketTasks.RunBackgroundTasks(); the UI just runs fine.用户界面运行良好。

How do I start the task in the background so that my User Interface is still responsive?如何在后台启动任务以使我的用户界面仍然响应?

EDIT:编辑:
The reason I started the task this way was because of exception handling.我以这种方式开始任务的原因是因为异常处理。 I can successfully start the task on a different thread as suggested with Task.Run(async () => await ticketTasks.RunBackgroundTasks());我可以按照Task.Run(async () => await ticketTasks.RunBackgroundTasks());的建议在不同的线程上成功启动任务。 But then I will not receive any exception if something goes wrong.但是,如果出现问题,我不会收到任何异常。

How can I start the task not blocking the UI and still receive the exception details if an exception is thrown?如果抛出异常,如何启动不阻塞 UI 的任务并仍接收异常详细信息?

The Internet states the following method:网上说的方法如下:

await Task.Run(() => ticketTasks.RunBackgroundTasks());

But this will not work because The await operator can only be used within an async method.但这不起作用,因为The await operator can only be used within an async method.

One way to do it is to wrap the task in an async event callback:一种方法是将任务包装在异步事件回调中:


public partial class MainWindow : Window
{
    // I mocked your missing types, replace with your own 
    class AssignTickets
    {
        public Task AssignTicketCreator() => Task.CompletedTask;
    }

    public class RunTicketTasks
    {
        public async Task RunBackgroundTasks()
        {
            AssignTickets assignTickets = new AssignTickets();
            int x = 0;
            while (true)
            {
                await assignTickets.AssignTicketCreator();
                await Task.Delay(1000);

                var isRunningOnDispatcher = Application.Current.Dispatcher ==
                    System.Windows.Threading.Dispatcher.FromThread(Thread.CurrentThread);
                Trace.WriteLine($"One second passed, running on dispatcher: {isRunningOnDispatcher}");

                // exception will also get thrown on the main thread
                if (x++ > 3) throw new Exception("Hello!");
            }
        }
    }

    public MainWindow()
    {
        InitializeComponent();

        // event fires on UI thread!
        this.Loaded += async (sender, args) =>
        {
            try
            {
                await new RunTicketTasks().RunBackgroundTasks();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        };
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM