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

C# Windows客户端GUI设计建议-从长时间运行的任务访问UI线程,c#,winforms,C#,Winforms,这里是Web开发人员,需要一些关于如何实现Windows窗体中的常见要求的建议 我有一个windows客户端应用程序,它调用单独项目中的业务对象来执行一些长时间运行的任务。与其他示例不同的是,流程位于另一个类库中,即Business.LongRunningTask() 我在客户机中有一个列表框,我希望通过任务登录到该列表框。当我从任务中登录到textbox时,我可以在UI线程上运行该进程,在textbox实例中传递并调用Application.DoEvents()。一切都很好,但并不优雅,并且不

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

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

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

如果我使用委托在单独的线程上运行长时间运行的进程,我将无法访问在windows客户端窗体中创建的文本框或委托,这将排除BeginInvoke调用

当然,这对我来说是个糟糕的设计,希望能得到一些反馈

我可以在UI线程上运行该进程 在 文本框和呼叫 当我登录到时,Application.DoEvents() 任务中的文本框

是的,您还可以传入一个iloggininterface实例,该实例用于将代码放入UI中写入文本框,从而处理所有漂亮的BginInvoke内容;)

如果我在服务器上运行长时间运行的进程 使用委托I分离线程 无法访问文本框或委托 在windows客户端窗体中创建 这就排除了BeginInvoke呼叫

啊。不需要。您只需将大部分调用返回到dispatcher线程,然后就可以访问您喜欢的所有UI元素。

您正在查找该类

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


您可以在这里找到一个完整的示例:

是的,避免
Application.DoEvents()


要将调用整理回UI线程,请调用this.Invoke(YourDelegate)

要从其他线程访问UI元素,可以使用control.Invoke调用所属线程上的委托。 我曾经使用它创建了一个实时日志屏幕,当另一个工作线程运行时,该屏幕由计时器更新。这里有一个简化版本:

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();
}

最后在这里使用@has的回复: