gpt4 book ai didi

c# - 在 c# winforms 应用程序的线程之间传递数据

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

<分区>

精简版:

我需要在线程之间来回传递复杂数据,一个线程是 WinForm,另一个线程调用在线翻译服务并更改 Winform 使用的所有数据。

长版:

将大量数据传递到在线翻译服务会使我的前端一次卡住几分钟,因此我试图将该逻辑移动到一个线程中。 Winform 广泛使用在线服务处理和返回新信息所需的数据。

我正在使用这段代码来启动线程:

threadWork tw = new threadWork();  //obj to hold data for thread
tw.settings = frmMain.projectSettings;
tw.CompletedEvent += tw_CompletedEvent; // callback event, returns data
ThreadPool.QueueUserWorkItem(doWork,tw); // kick off thread

接收回调码:

void tw_CompletedEvent(projectFormat settings)
{
frmMain.projectSettings = settings;
NotifyLoadTransationKeys(frmMain.projectSettings.translationKeys,frmMain.projectSettings.translatedLanguages);

}

这基本上造成了这个错误:

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

所以我找到了this建议在 Program.cs 中替代使用 [STAThread] [sta = single thread apartment](默认 c# winform 入口点)

using System.Threading;
Thread t = new Thread(new ThreadStart(StartNewStaThread));
// Make sure to set the apartment state BEFORE starting the thread.
t.ApartmentState = ApartmentState.STA;
t.Start();
private void StartNewStaThread() {
Application.Run(new Form1());
}

我的 C# 应用程序中的所有内容都从“Program.cs”开始,所以我尝试了上述建议:

static class Program
{
public static translationUtil TranslationUtil; //location of time intensive webservice
public static projectFormat projectSettings; //data that needs sharing

static void Main() // prog entry point
{
ProgramCode pc = new ProgramCode();
pc.Main();
}
}

class ProgramCode
{
public void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

Thread t = new Thread(new ThreadStart(StartNewStaThread));
t.ApartmentState = ApartmentState.STA;
t.Start();
}

private void StartNewStaThread()
{
Application.Run(new Main());
}
}

在上面的代码中,我尝试将共享资源移动到“Program.cs”,然后创建一个新类和线程来保存我的 winform,但这仍然给我带来跨线程问题(与以前相同的错误)!有没有人对如何在我的情况下成功使用线程和共享数据提出建议?

更新:@HenkHolterman 迄今为止最好地回答了我的问题,但在研究了他给我的答案(使用“调用”)后,我已经多次遇到这段代码

if (control.InvokeRequired) {
control.Invoke(new ControlStringConsumer(SetText), new object[]{control, text}); // invoking itself
} else {
control.Text=text; // the "functional part", executing only on the main thread
}

按照问题...上面的“if”语句似乎只是设置文本而没有调用(在“if”的分支之一上,我是否也应该遵循这种模式,它有什么用?

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