C# - 在单独线程中将条目添加到列表时,列表框未更新

C# - Listbox not updated when an entry is added to the list in a seperate thread

我有一个 static class 可以将日志打印到列表框,这样我就可以全局使用它,所以我使用了在我的 cls_globalvariables static [=17] 中定义的 BindingList 的全局实例=].我在 UI 构造函数中将 BindingList 绑定到 UI 的列表框。

public static class cls_globalvariables
{
    public static BindingList<string> logList = new BindingList<string>();
  ....
}

static class LOGS
{

    public static void LOG_PRINT(string logMessage, bool isNotError)
    {
        string now = DateTime.Now.ToString();
        try
        {
            if (logMessage == "") return;
            if (!isNotError)
                logMessage = "<<<ERROR>>>" + logMessage;

            // Output to text file.
            using (StreamWriter w = System.IO.File.AppendText(cls_globalvariables.systemlogpath))
            {
                w.WriteLine("[" + now + "][" + logMessage + "]");
                w.Close();
            }
            // Save to memory
            cls_globalvariables.logList.Add("[" + now + "][" + logMessage + "]");
        }
        catch (Exception)
        { }
    }
}

public partial class Form1: Form
{
    public Form1()
    {
        InitializeComponent();
        listBox1.DataSource = cls_globalvariables.logList;
    }
}

但是,我只在我的 backgroundworker 中调用 LOGS.LOG_PRINT,所以它在另一个线程中执行。列表框延迟更新,直到后台工作人员完成其过程。我错过了什么吗?

您不应在后台线程中更新 BindingList 实例,因为您将其绑定到主用户界面线程。用户界面控件并非设计为从创建它的线程以外的任何线程调用。

因此我建议您的后台线程使用新消息回调主线程,然后主线程将消息添加到绑定列表。

将 SynchronizationContext.Current 从主线程传递到后台线程,然后在 LOGS.LOG_PRINT 方法中,您应该使用 lambda 调用 SynchronizationContext 的 Post 方法来更新列表.像下面这样...

_syncContext.Post((_) => cls_globalvariables.logList.Add(str), null);

其中str是新构造的日志字符串。