使用线程遍历数组以每秒显示一项
本文关键字:显示 一项 线程 遍历 数组 | 更新日期: 2023-09-27 17:49:41
我试图创建一个while或for循环,使用线程按顺序显示索引字符串或int,以便它自动更改为下一个索引。这是我目前得到的。它在c#中,但计划在java中使用相同的信息。
private void button1_Click(object sender, EventArgs e)
{
string st = "hello my name is miroslav glamuzina";
string[] arr = st.Split(' ');
int i = 0;
while (i < arr.Length)
{
Thread.Sleep(50);
label1.Text = arr[i];
i++;
}
}
TPL加上await
使得真的很容易:
private async void button1_Click(object sender, EventArgs e)
{
string st = "hello my name is miroslav glamuzina";
string[] arr = st.Split(' ');
foreach(string word in arr)
{
label1.Text = word;
await Task.Delay(50);
}
}
另一个选择是使用微软的响应式扩展(Rx)为您处理异步性。
下面是你的代码:private SerialDisposable _subscription = new SerialDisposable();
private void button1_Click(object sender, EventArgs e)
{
string st = "hello my name is miroslav glamuzina";
string[] arr = st.Split(' ');
_subscription.Disposable =
Observable
.Interval(TimeSpan.FromMilliseconds(50.0))
.Select(i => arr[(int)i])
.Take(arr.Length)
.ObserveOn(this)
.Subscribe(word =>
{
label1.Text = word;
});
}
现在,这段代码的好处是Subscribe
方法返回一个IDisposable
,可以用来在可观察对象查询完成之前停止它。有点像取消请求。现在,通过将此与SerialDisposable
耦合,您将获得良好的行为,如果您的用户多次单击按钮,那么只有最新的订阅到可观察的查询将运行,如果现有的订阅正在运行,它将首先停止。
Rx还处理将代码推送到后台线程而不需要考虑它。ObserveOn(this)
调用使线程重新在UI上运行,以便可以更新标签。
此代码在UI线程中工作,因此thread. sleep (X)休眠主应用程序线程。我建议你使用BackgroundWorker。
private void button1_Click(object sender, EventArgs e)
{
System.ComponentModel.BackgroundWorker bw = new System.ComponentModel.BackgroundWorker();
bw.DoWork += (sender, e) =>
{
string st = "hello my name is miroslav glamuzina";
string[] arr = st.Split(' ');
System.ComponentModel.BackgroundWorker worker = sender as System.ComponentModel.BackgroundWorker;
for (int i = 0; i < arr.Length; i++)
{
Thread.Sleep(500);
worker.ReportProgress(i, arr[i]);
}
};
bw.ProgressChanged += (sender, e) =>
{
label1.Text = e.UserState as string;
};
bw.RunWorkerAsync();
}
在这里使用线程确实是多余的。我也认为Task.Delay
是最好的方法,如果你可以使用c# 5.0 async/await
。然而,作为一种替代方法,这里有另一种使用yield
和计时器的方法,也是基于编译器生成的状态机。它适用于c# 2.0及更高版本:
private void button1_Click(object sender, EventArgs e)
{
this.button1.Enabled = false;
Iterate();
}
IEnumerable GetIterator()
{
string st = "hello my name is Noseratio";
string[] arr = st.Split(' ');
foreach (var s in arr)
{
label1.Text = s;
yield return Type.Missing;
}
}
void Iterate()
{
var enumerator = GetIterator().GetEnumerator();
var timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += delegate
{
if (!enumerator.MoveNext())
{
timer.Dispose();
this.button1.Enabled = true;
}
};
timer.Start();
}