Windows 客户端 GUI 设计建议 - 从长时间运行的任务访问 UI 线程
本文关键字:运行 长时间 任务 访问 线程 UI GUI 客户端 Windows | 更新日期: 2023-09-27 17:56:36
Web 开发人员在这里,需要一些关于如何实现 Windows 窗体中必须满足的常见要求的建议。
我有一个 Windows 客户端应用程序,它调用单独项目中的业务对象来执行一些长时间运行的任务。与其他示例的不同之处在于,该进程存在于另一个类库中,即 Business.LongRunningTask();
我在客户端中有一个列表框,我希望通过任务登录到该列表框。我可以在 UI 线程上运行该过程,在文本框的实例中传递并在从任务内登录到文本框时调用 Application.DoEvents()。一切都很好,但不优雅,宁愿不调用Application.DoEvents();
如果我使用委托在单独的线程上运行长时间运行的进程,则无法访问在 Windows 客户端表单中创建的文本框或委托,从而排除了 BeginInvoke 调用。
当然,这是我的糟糕设计,希望得到一些反馈。
> 您正在寻找 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();
}