gpt4 book ai didi

c# - 从 Winforms 中的外部线程访问 UI

转载 作者:太空宇宙 更新时间:2023-11-03 19:51:01 24 4
gpt4 key购买 nike

在 WPF 中,可以使用如下内容:

Application.Current.Dispatcher.BeginInvoke(new Action(() => Form1.grid.Items.Refresh()));

在主线程之外访问 UI 功能。然而,在 Winforms 中,没有相同的功能。从我的“工作”线程访问存在于我的 Form1 类中的 BindingList 的最简单方法是什么?目前我在尝试访问“Form1.record_list”时遇到以下错误:

System.InvalidOperationException: Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.

编辑:感谢到目前为止的帮助,但我对“this.Invoke”一头雾水。我在单独线程中的方法没有“调用”。

到目前为止,这是我的代码示例。

        public static void listen(IPEndPoint server_ip)
{
Console.WriteLine("In listen");
while (true)
{
try
{
byte[] received_bytes = udp_client.Receive(ref server_ip);
string received_data = Encoding.ASCII.GetString(received_bytes);
Record record = JsonConvert.DeserializeObject<Record>(received_data);
Form1.record_list.Add(record); //This is where I assume the problem spawns
}

catch (Exception e)
{
Console.WriteLine(e);
}
}
}




public partial class Form1 : Form
{
public static BindingList<Record> record_list = new BindingList<Record> { };
public static DataGridViewCellStyle style = new DataGridViewCellStyle();
public Form1()
{
InitializeComponent();
Thread thread = new Thread(SCMClient.connect);
thread.IsBackground = true;
thread.Start();
FillData();
}

protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
foreach (DataGridViewRow row in dataGridView.Rows)
{
for (var i = 0; i < row.Cells.Count; i++)
{
Console.WriteLine(row.Cells[i].Value);
if (row.Cells[i].Value as string == "OK")
{
row.Cells[i].Style.BackColor = Color.Red;
Console.WriteLine("IF WAS TRUE");

}
}
}
}

我认为这里的具体问题是当我将 Records 添加到 Forms1.record_list 时。我不确定如何在不导致跨线程错误的情况下将项目添加到该列表...

最佳答案

您必须只能从您的 UI 线程访问您的 UI。但是你可以使用 Control.Invoke方法 - Form 是一个 Control - 以确保您的代码从 UI 线程运行。

另外,您有一个静态的 BindingList,但我假设您想以特定的形式显示该列表的内容。您应该使 BindingList 成为实例成员...或者获取对有效表单的引用。 Control.Invoke 方法不是静态的。

有几种方法可以做到这一点。我会这样做:

首先,在您的 Form 类中创建一个方法,将记录添加到列表中。

public void AddRecord(Record r) {
if(this.InvokeRequired) {
this.Invoke(new MethodInvoker(() => this.AddRecord(r)));
} else {
this.record_list.Add(r);
}
}

其次,您需要有对表单的引用(在下一步中,即 theForm 变量)。

然后,在您的监听器方法中,调用 AddRecord 方法,而不是直接将记录添加到您的 BindingList 中。

public static void listen(IPEndPoint server_ip)
{
Console.WriteLine("In listen");
while (true)
{
try
{
byte[] received_bytes = udp_client.Receive(ref server_ip);
string received_data = Encoding.ASCII.GetString(received_bytes);
Record record = JsonConvert.DeserializeObject<Record>(received_data);
theForm.AddRecord(record); // You need a Form instance.
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}

关于c# - 从 Winforms 中的外部线程访问 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39513650/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com