我有一个包含许多标签的表单,我想在很多线程中同时写入它们
(UI BackGroundWorker
等)
我已编写此代码,它正在主标签上工作(应用启动时可见的标签)
public struct Struct_Append
{
public RichTextBox Screen;
public string Message;
public Color Color;
}
public void AppendAllTextAllScreen (Struct_Append append )
{
RichTextBox screenToPrint = append.Screen;
Font font = new Font("Tahoma", 8, FontStyle.Regular);
if (screenToPrint.InvokeRequired) //&& this.Visible)
{
append.Message = append.Message + "\n";
try
{
this.Invoke(new Action<Struct_Append>(AppendAllTextAllScreen), new object[] {
append });
}
catch(Exception ex)
{
//handle exception
}
return;
}
append.Message = append.Message + "\n";
screenToPrint.SelectionFont = font;
screenToPrint.SelectionColor = append.Color;
screenToPrint.AppendText(append.Message);
}
它可以在任何线程中工作,但是一旦我将屏幕设置为其他一些选项卡,并将其激活
Struct_Append structAppend1 = new Struct_Append();
structAppend1.Screen = scrnSta1;
structAppend1.Color = Color.Bisque;
structAppend1.Message = "THIS IS A TEST";
AppendAllTextAllScreen(structAppend1);
VisualStudio2013卡住了,重新启动!!!!
但是当我在没有DEBUG的情况下运行它时运行良好
编辑我使用的代码产生了错误
这是我用来测试上面的appendText
方法
private async void DoSomthing()
{
Task.Run(() =>
{
_Append structAppend1 = new _Append();
structAppend1.Screen = ScrnSta1; ;
structAppend1.Color = Color.Bisque;
structAppend1.Message = "THIS IS A TEST";
for (int i = 0; i < 5; i++)
{
AppendAllTextAllScreen(structAppend1);
}
});
Task.Run(() =>
{
_Append structAppend = new _Append();
structAppend.Color = Color.Aquamarine;
structAppend.Message = "THIS IS A TEST";
structAppend.Screen = ScrnSta2;
for (int j = 0; j < 5; j++)
{
AppendAllTextAllScreen(structAppend);
}
});
}
scrnsta1 / 2是我的Form
(主UI线程)中的两个单独的选项卡,我从那里调用此方法(UI线程)
我在这里错过了什么?
答案 0 :(得分:1)
据我了解,必须通过Control
的{{3}}来访问来自不同线程的Windows窗体控件,这需要定义合适的委托。在您的示例中,这些委托基本上是DoSometing
实现中使用的lambda表达式。
答案 1 :(得分:1)
我建议在不使用调用的情况下继续UI线程上的任务。它更安全,更不容易出错:Task continuation on UI thread
Task UITask= task.ContinueWith(() =>
{
this.TextBlock1.Text = "Complete";
}, TaskScheduler.FromCurrentSynchronizationContext());