[英]Text not updating
我有兩個類;一個叫Form1.cs,另一個叫NoteThreader.cs,這是兩個類的內容:
Form1.cs中:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace HitMachine
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void updateText(string theText)
{
label1.Text = theText;
}
private void Form1_Load(object sender, EventArgs e)
{
XML.LoadMP3.loadFile(XML.XmlParser.ParseDocument("music"));
Threading.NoteThreader.createTimer();
}
}
}
NoteThreader.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace HitMachine.Threading
{
public class NoteThreader
{
public static Thread createTimer()
{
Thread t = new Thread(threadDeligation);
t.Start();
return t;
}
public static int time = 0;
static void threadDeligation()
{
for (; ; )
{
Form1 a = new Form1();
a.updateText(time);
time++;
}
}
}
}
代碼運行無任何異常或錯誤; 但是它不會更新文本。 我猜是因為調用該方法的線程與更新文本的線程不同?
我嘗試調用它,但無法執行。 我在threadDeligation中運行了一個MessageBox,並且工作正常。
在您的threadDeligation
方法中,每次循環執行時都在創建一個Form1
的新實例。 這不會更改您正在查看的Form1
實例中的文本。
您將需要將Form1
的正確實例傳遞給createTimer
方法(然后將其傳遞給threadDeligation
方法)。
您可以這樣處理:
private void Form1_Load(object sender, EventArgs e)
{
XML.LoadMP3.loadFile(XML.XmlParser.ParseDocument("music"));
Threading.NoteThreader.createTimer(this);
}
接着:
public static Thread createTimer(Form1 theForm)
{
Thread t = new Thread(() => threadDeligation(theForm));
t.Start();
return t;
}
public static int time = 0;
static void threadDeligation(Form1 theForm)
{
for (; ; )
{
theForm.updateText(time);
time++;
}
}
這應該給你如何在你的代碼通過周圍物體的總體思路,但由於從非UI線程更新UI元素,不支持將無法正常工作。 您將需要使用BackgroundWorker
類。
for (; ; )
{
Form1 a = new Form1();
a.updateText(time);
time++;
}
Form1
對象。 a.Show();
在哪里a.Show();
? 如果要顯示計時器的值,則應保留對適當的Form1
對象的引用。
因此,這里有很多問題。 首先是其他答案提到的顯而易見的內容。 您正在創建Form1
新實例並調用其方法,然后修改其標簽。 您沒有修改要顯示給用戶的表單; 它沒有改變。
如果要保留正在使用的表單的實例,則會遇到從另一個線程修改表單的問題。 那是不允許的。 在Winform編程中,只允許從創建它們的線程訪問Control
對象。 否則會出錯。
為了解決這個問題,您可以調用主UI線程進行更新。 但是,現在您處於發送命令以盡可能快地發送標簽更新標簽的位置。 那...非常非常非常快。 如此之快以至於屏幕根本無法更新。 由於發送的命令數量巨大,您將開始滯后甚至凍結。
似乎您想創建某種臨時時鍾,在其中您每隔X個時間間隔增加一個數字。 假設每秒一次(但您可以輕松地將其更改為10毫秒或任何其他時間)。 為了在X時間間隔內執行某項操作,我們需要使用Timer
。
void Form1_Load(object sender, EventArgs e)
{
var timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += timer_Tick;
timer.Start();
}
private int time = 0;
void timer_Tick(object sender, EventArgs e)
{
label1.Text = time.ToString();
time++;
}
如果按照命名約定,而不是每隔X間隔執行一次操作,而不是每隔X間隔執行一次操作,而是根據生產進度進行一些富有成效的工作並更新用戶界面,那么那就是另一個問題了。 一個不錯的選擇是使用Progress
類使用一些非UI任務的Progress
來更新UI。 它可能看起來像這樣:
void Form1_Load(object sender, EventArgs e)
{
Progress<string> progress = new Progress<string>(updateText);
Thread thread = new Thread(() => NoteThreader.DoWork(progress));
thread.Start();
}
public class NoteThreader
{
public static void DoWork(IProgress<string> progress)
{
for (int i = 0; i < 10; i++)
{
Thread.Sleep(1000);//placeholder for real work
progress.Report(i.ToString());
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.