1

多年来,我一直在编写 ASP.NET Web 应用程序,但还没有真正从事过大型 Windows 窗体项目。我现在需要研究一个,所以我正在寻找一些关于如何理想地构建大型 Windows 窗体项目的指针。更具体地说,我想知道如何处理多个线程。假设您有一个需要一些时间才能完成的过程 - 您不希望 ui 窗口冻结并且没有响应。所以这个逻辑需要在一个单独的线程中移动。如果此线程访问 UI,则会导致异常。Invoke 似乎可以解决问题,但看起来非常丑陋且写和读起来很麻烦!

那么,实际上,最佳实践是什么?应该启动什么类型的线程,这些线程应该如何在 UI 和逻辑之间进行拆分?有什么示例代码可以开始吗?

4

3 回答 3

3

这是使用 backgroundworker 的简短方法

        public Form1()
    {
        InitializeComponent();

        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true; //set to true to fire the progress-changed event
        worker.DoWork += doWork;
        worker.ProgressChanged += progressChanged;
    }

    void progressChanged(object sender, ProgressChangedEventArgs e)
    {
        int progress = e.ProgressPercentage; //Progress-Value
        object userState = e.UserState; //can be used to pass values to the progress-changed-event
    }

    void doWork(object sender, DoWorkEventArgs e)
    {
        object argument = e.Argument; //Parameters for the call
        bool cancel = e.Cancel; //Boolean-Value for cancel work
        object result = e.Result; //Object for a return-value
    }
于 2012-06-12T07:18:39.540 回答
2

一旦您使用不同的线程,您将不得不在触摸 UI 时切换回 UI 线程。

someForm.BeginInvoke()可以做到这一点,但还有更多选择。

BackgroundWorker 可以为您进行切换。

在 .NET 4.5/ C# 5 中,您可以使用async/await;将在原始线程上调用延续。

一般来说,尽量从 UI 中解开逻辑,这样你就不需要太频繁地切换线程。

于 2012-06-12T07:20:38.287 回答
2

有很多方法可以实现 UI 响应、执行长时间运行的任务、实现并行性。您必须为您的应用选择正确的方式 -

Jon Skeet 的这篇文章总是一开始就是一个奖励。

  1. 您可以根据您的应用程序设计和要求使用这些样式中的任何一种异步调用同步方法

  2. 比较困难的情况,比如协调多个线程的工作,或者处理阻塞的线程

  3. 有多种方法可以向客户端代码公开异步功能。在此处阅读基于事件的异步模式 - 它规定了类呈现异步行为的推荐方式。

  4. 当您有一个长时间运行的任务时,后台工作人员会派上用场。

希望这能给你一个良好的开端。

于 2012-06-12T08:46:34.250 回答