C# C语言中的线程安全#

C# C语言中的线程安全#,c#,multithreading,winforms,thread-safety,C#,Multithreading,Winforms,Thread Safety,我目前被分配了一个项目,该项目是几年前在C#中实施的。 它由框架和一些excel文件提取组成,但问题是 该项目已严重损坏/过时,我必须更改一些功能并添加一些新功能 有些库只有在.NET framework 3.0之后才受支持,我需要在新功能中使用它们,而当前项目所基于的框架是2.0或更低,因此更改框架会引发一些线程安全问题 例如,在两个分部类(设计文件代码和后端代码)之间,试图更改一个标签的值会引发一个错误,表示我无法编辑当前正在使用的某些内容。。。 我在其中一个标签上使用了委托,效果很好。然后

我目前被分配了一个项目,该项目是几年前在C#中实施的。 它由框架和一些excel文件提取组成,但问题是 该项目已严重损坏/过时,我必须更改一些功能并添加一些新功能

有些库只有在.NET framework 3.0之后才受支持,我需要在新功能中使用它们,而当前项目所基于的框架是2.0或更低,因此更改框架会引发一些线程安全问题

例如,在两个分部类(设计文件代码和后端代码)之间,试图更改一个标签的值会引发一个错误,表示我无法编辑当前正在使用的某些内容。。。 我在其中一个标签上使用了委托,效果很好。然后另一个文本框引发了另一个错误。。 那么,有没有一个选项可以封装整个代码并将线程安全性应用于整个代码,而不必遵循发生错误的每一行


根据评论编辑

异常

保存链接时出现异常。异常:System.InvalidOperationException:跨线程操作无效:从创建控件的线程以外的线程访问控件“picLinkUBKCross”。

编码谁会失败

this.picLinkUBKCross.Image = ((System.Drawing.Image) resources.GetObject("picLinkUBKCross.Image"))); 
this.picLinkUBKCross.Location = new System.Drawing.Point(367, 57);
this.picLinkUBKCross.Name = "picLinkUBKCross"; 
this.picLinkUBKCross.Size = new System.Drawing.Size(56, 35); 
this.picLinkUBKCross.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.picLinkUBKCross.TabIndex = 14;
this.picLinkUBKCross.TabStop = false; 

如果您的项目在它的多线程代码中包含错误,那么在新框架和线程处理中,从奇怪的小故障到实际的异常(这是一件好事),除了一个接一个地处理这些错误之外,您别无选择。用一颗银弹修复所有的错误代码是没有魔力的。

所以如果你已经切换了框架,我想你也切换了你的Visual Studio版本

在VS中,如果希望看到
跨线程异常
,您可以进行配置,我认为在您的旧版本中,此提示只是关闭了。所以,您的所有问题都已经存在于旧代码中,但现在您又看到了它

如果您试图从gui控件设置(有时甚至获取)某些信息,则必须确保在gui线程中而不是从任何其他线程中进行设置。问题是它可以工作,但不能保证(可能只是在客户机器上崩溃)

请将这些异常视为工具中的一个真正的问题,必须尽快修复。

在gui线程中调用
WindowsFormsSynchronizationContext.Current并将接收到的对象传递给其他线程,以便它们可以对其调用
Post()
Send()
,或者如果您可以直接访问控件,只需对其调用
control.Invoke()
control.BeginInvoke()


也许你也应该看看这个。

这是一个什么样的项目,winforms?至少发布引发异常的部分代码以及异常的详细信息。发布错误,否则很难理解真正的问题。是的,这是winforms<代码>保存链接时出现异常。异常:System.InvalidOperationException:交叉线程操作无效:从创建控件的线程以外的线程访问控件“picLinkUBKCross”。
this.picLinkUBKCross.Image=((System.Drawing.Image)(resources.GetObject(“picLinkUBKCross.Image”);this.picLinkUBKCross.Location=新系统图纸点(367,57);this.picLinkUBKCross.Name=“picLinkUBKCross”;this.picLinkUBKCross.Size=新系统图纸尺寸(56,35);this.picLinkUBKCross.SizeMode=System.Windows.Forms.PictureBoxSizeMode.StretchImage;this.picLinkUBKCross.TabIndex=14;this.picLinkUBKCross.TabStop=false
public void SetLabel(string p_sNote){if(lblLoadStatus.InvokeRequired){lblLoadStatus.BeginInvoke(new MethodInvoker(delegate{SetLabel(p_sNote);}}}else{lblLoadStatus.Text=p_sNote;}}
这是一条现在可以正常工作的固定线路,因此我必须对所有导致问题的其他线路应用相同的方法?除了在每种情况下引用的控件的明显变化外,是的。基本上,每个非UI线程函数都需要检查是否需要调用,如果需要,则需要调用。