从引发事件的外部线程更新控件

Update a control from an external thread rising an event

这是上下文:在 Winform 中,我使用导入库中的对象,然后启动它的主要方法。该对象在其进行时引发事件以提供进程状态(我在其上订阅了我的一种 winform 方法以获取此状态)。 main方法returns一个bool,只有当它已经结束了它的进程(所以事件上升允许知道进程的演变)

问题是:我订阅事件的方法很好,它将状态写入控制台并在列表框中添加状态(使用 BeginInvoke) 每次事件发生时,都会将写入控制台的信息放入(正是我需要的),但是列表框显示为空白,直到 main 方法返回其值,然后最终显示其内容.

我希望列表框(或任何控件)在收到事件的确切时刻显示从事件返回的状态,否则我无法在此过程中通知我的用户。

这是我的代码,你能帮帮我吗?

Local method rised by object from library :

        private void ClientOnUpdate(object sender, EventParameters UpdateEventArgs)
    {
        //Instant write
        Console.WriteLine("Update Event Parameters: {0}", UpdateEventArgs);

        //Wait for the return of the Start method to show results inf lisbox
        lbErrors.BeginInvoke((Action)delegate()
        {
            lbErrors.Items.Add(String.Format("Update Event Parameters: {0}", UpdateEventArgs));
        });

    }

Launching the main method of the object from the library:

        private void Launch()
    {
        lbErrors.Items.Clear();
        Client cl1 = new Client();
        bool res = cl1.Start();

        if (res == true)
        {
            //do stuff ...
        }
        else
        {
            //do stuff ...
        }
    }

The results (status get from the fired event):

  1. 开始
  2. 第 1 步正常
  3. 第 2 步正常
  4. 第 3 步确定
  5. 结束

您在执行 Launch 后看到列表项的原因是您的 private void Launch() 运行 同步并阻塞了 UI 线程。当 UI 线程准备好执行您的方法时,列表框会更新。

您可以使用 BackgroundWorkerTask 来 运行 您的 Launch 方法吗?这将释放 UI 线程。如果可能,您也可以将 Launch 方法设为 async

例如使用Task:

Task.Run(() => Launch());

请注意,在 Task 中调用 UI 也需要 InvokeBeginInvoke