我正在尝试将循环内容显示到我的UI。首先,我不确定我是以正确的方式接近这个(使用WinForms),但这就是我正在做的事情:
foreach (string item in stringArray)
{
Thread thread = new Thread(delegate()
{
UpdatedResultEvent(item);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
我希望这是足够的信息,但如果不是,那么我将在这里详细介绍。
我有两个类,我的Program.cs(WinForm)和另一个名为logicClass的类。我将我的Program对象的实例传递给我的logicClass。我的logicClass有一个委托,该签名与我的Program类中的方法匹配。作为委托传递的方法是
public void UpdateResultsOnScreen(string newContent)
{
txtResults.Text += newContent;
}
错误消息是
跨线程操作无效:从线程访问控制 除了在
上创建的主题
修改
与进度条的工作方式类似,目标是让控件实时更新。目前,即使它确实有效,线程也不会将“结果”返回到屏幕,直到线程完成。
答案 0 :(得分:1)
即使您正在设置ApartmentState,也必须在从另一个(非UI)线程访问时调用UI控件。
确保在UpdateResultEvent方法中调用UI控件。
无论如何,你正在做的不是一个好主意,考虑使用ThreadPool或Parallel.ForEach
它会自动扩展你的代码,产生一堆线程可以真正降低性能,特别是如果你的集合中有很多项目。
答案 1 :(得分:1)
使用它(如果你在WinForms上):
public void UpdateResultsOnScreen(string newContent)
{
txtResults.BeginInvoke(
new Action<string>((value) =>
{
txtResults.Text += value;
}),
newContent);
}
同样,动画线表示,请考虑使用ThreadPool
或Parallel.ForEach
。
答案 2 :(得分:0)
这样做怎么样?
public void UpdateResultsOnScreen(string newContent)
{
if(txtResults.InvokeRequired)
{
txtResults.Invoke(
new Action<string>(content => txtResults.Text += content), newContent);
return;
}
txtResults.Text += newContent;
}