微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

当创build一个新线程时,对GUI的更改没有被制作C#

有一些帮助,我设法创build一个新的线程,虽然方法似乎执行,方法的条件或者使绿色或红色的灯光出现,虽然当运行方法(Check1..etc)没有新线程的变化被反映在GUI上(例如Red / Green Light出现),但是当创build一个新线程并运行该方法时,这些改变不会反映在Form / GUI上。

// Method / Action to start the checks private void StartChecks_Click(object sender,EventArgs e) { Thread t = new Thread( o => { InitChecks(); }); t.Start(); } // Check1 public void Check1() { // lets grabs the info from the config! var lines = File.ReadAllLines("probe_settings.ini"); var dictionary = lines.Zip(lines.Skip(1),(a,b) => new { Key = a,Value = b }) .Where(l => l.Key.StartsWith("#")) .ToDictionary(l => l.Key,l => l.Value); // lets set the appropriate value for this check field label1.Text = dictionary["#CheckName1"]; // lets define variables and convert the string in the dictionary to int for the sock.connection method! int portno1; int.TryParse(dictionary["#PortNo1"],out portno1); // Convert hostname to IP,performance issue when using an invalid port on a hostname using the TcpClient class! IPAddress[] addresslist = Dns.GetHostAddresses(hostname2); foreach (IPAddress theaddress in addresslist) { // Attempt to create socket and connect to specified port on host TcpClient tcP = new System.Net.sockets.TcpClient(); try { tcP.ReceiveTimeout = 1; tcP.SendTimeout = 1; tcP.Connect(theaddress,portno1); displayGreen1(); tcP.Close(); } catch { displayRed1(); } } } // Change the lights when the condition is met public void displayGreen1() { pictureBox2.Visible = false; pictureBox1.Visible = true; } private void displayRed1() { pictureBox2.Visible = true; pictureBox1.Visible = false; }

如何使用Mono在Linux摄像头捕捉?

.NET字典键作为列表框数据源

令人难以置信的奇怪的文件创build时间问题

WindowsIdentity缺less组 – 尤其是pipe理员组

wasabi阻止Azure缩放收集数据的频率如何?

这是因为UI控件只能从UI线程更新。 当你不创建一个新线程时,更新控件的代码在UI线程上运行,所以它可以像你期望的那样工作。 当你创建一个新的线程,因为这个线程不是 UI线程,应该更新控件的代码不能这样做。

您可以通过更改方法调用来确保更新控件的代码在UI线程上运行: –

this.BeginInvoke(new Action(() => displayRed1()));

this.BeginInvoke(new Action(() => displayGreen1()));

顺便说一句(与您目前的问题无关): –

尽量避免创建一个明确的线程。 而是使用线程池为您管理线程,例如ThreadPool.QueueUserWorkItem(x => InitChecks()) 。 (请注意,这仍然会在非UI线程上运行,因此您仍然需要使用BeginInvoke() ,如上所述)。 线程池知道什么时候创建和执行一个线程,使用它最终会使你的代码更有效率。

尽量避免捕获try{...}catch{...} 所有异常类型。 这就是说,当任何类型的异常被抛出时,你的代码知道该怎么做。 相反,只有捕获你确切知道如何处理的异常,

例如

try { ... } catch(TcpException) { ... } catch(AnotherKNownException) { ... } ...

请注意,只要在退出块时重新抛出异常,也可以为所有异常类型设置catch块,

例如

try { ... } catch(KNownException) { ... } catch(Exception) { // perform some logging,rollback,etc. throw; }

这就是WinForms的设计。 您不能从另一个线程进行更改。 解决方案通常是使用异步委托。

首先添加这个声明

public delegate void MyDelegate1 (); public delegate void MyDelegate2 ();

那么当你在另一个线程中你应该这样做:

MyDelegate1 d1= new MyDelegate1 (displayGreen1); this.BeginInvoke(d1); MyDelegate2 d2= new MyDelegate2 (displayRed1); this.BeginInvoke(d2);

在你的技能水平上,最好是:

使用计时器的形式来检查一些状态变量(比如bool _pb1Visible和bool _pb2Visible )

在计时器事件更新pictureBox知名度

在线程中,只更新上面提到的bool成员变量。

它会像魅力一样工作!

简单的例子:

在您的Check1()方法中,而不是:

displayGreen1();

_pb1Visible=true; _pb1Visible=false;

而不是

displayRed1();

_pb1Visible=false; _pb1Visible=true;

把计时器放在窗体上。 在计时器事件中,执行以下操作:

pictureBox2.Visible = _pb2Visible; pictureBox1.Visible = _pb1Visible;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐