Windows 客户端 GUI 设计建议 - 从长时间运行的任务访问 UI 线程

本文关键字:运行 长时间 任务 访问 线程 UI GUI 客户端 Windows | 更新日期: 2023-09-27 17:56:36

Web 开发人员在这里,需要一些关于如何实现 Windows 窗体中必须满足的常见要求的建议。

我有一个 Windows 客户端应用程序,它调用单独项目中的业务对象来执行一些长时间运行的任务。与其他示例的不同之处在于,该进程存在于另一个类库中,即 Business.LongRunningTask();

我在客户端中有一个列表框,我希望通过任务登录到该列表框。我可以在 UI 线程上运行该过程,在文本框的实例中传递并在从任务内登录到文本框时调用 Application.DoEvents()。一切都很好,但不优雅,宁愿不调用Application.DoEvents();

如果我使用委托在单独的线程上运行长时间运行的进程,则无法访问在 Windows 客户端表单中创建的文本框或委托,从而排除了 BeginInvoke 调用。

当然,这是我的糟糕设计,希望得到一些反馈。

Windows 客户端 GUI 设计建议 - 从长时间运行的任务访问 UI 线程

> 您正在寻找 BackgroundWorker 类。

若要在后台执行耗时的操作,请创建一个BackgroundWorker并侦听报告操作进度并在操作完成时发出信号的事件。

你可以在这里找到一个完整的例子:http://msdn.microsoft.com/en-us/library/b2zk6580(v=VS.100).aspx#Y1351

我可以在 UI 线程上运行该过程 实例中的传递 文本框和调用 Application.DoEvents() 当我登录时 任务中的文本框。

是的,您还可以传入一个 ILoggingINnterface 的实例,该实例用于放入代码以从 UI 内部写入文本框,从而处理所有不错的 BginInvoke 内容;)

如果我在 使用委托 I 的单独线程 无法访问文本框或委托 在 Windows 客户端窗体中创建 这排除了 BeginInvoke 调用。

啊。不。您只需最常调用回调度程序线程,然后您就可以访问您喜欢的所有 UI 元素。

是的,避免Application.DoEvents()

若要将调用封送回 UI 线程,请调用this.Invoke(YourDelegate)

若要从其他线程访问 UI 元素,可以使用控件。调用以调用所属线程上的委托。我曾经使用它来创建实时日志屏幕,该屏幕在不同的工作线程运行时从计时器更新。下面是一个简化版本:

public class DifferentClassLibrary
{
    public delegate void StringDataDelegate(string data);
    public event StringDataDelegate UpdatedData;
    public void DoStuff()
    {
        if (UpdatedData != null)
        {
            Thread.Sleep(10000);
            UpdatedData("data");
        }
    }
}

在 winform 中:

public void UpdateTextBoxCallback(string data)
{
    if (uiTextBoxLiveLogView.InvokeRequired)
    {
        uiTextBoxLiveLogView.Invoke(new DifferentClassLibrary.StringDataDelegate(UpdateTextBoxCallback), data);
    }
    else
    {
        uiTextBoxLiveLogView.Text += data;
    }
}
void Main()
{
    DifferentClassLibrary test = new DifferentClassLibrary();
    test.UpdatedData += UpdateTextBoxCallback;
    Thread thread = new Thread(new ThreadStart(test.DoStuff));
    thread.Start();
}