在 C# 中以随机顺序线程 运行
Threads running in random order in C#
我认为标题不言自明。只是我有一些 运行 随机顺序而不是我计划的顺序的线程。
这是示例代码:
event strHandler strChanged;
delegate void strHandler(string str);
public Form1()
{
InitializeComponent();
strChanged += new strHandler(updatestr);
}
public void updatestr(string str)
{
Thread th = new Thread(new ParameterizedThreadStart(updatethr));
th.IsBackground = true;
th.Start(str);
}
object obj = new object();
private void updatethr(object str)
{
lock (obj)
{
SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str);
Thread.Sleep(1000);
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Text = write();
}
private string write()
{
string res = "";
strChanged(res);
for (int i = 0; i <= 5; i++)
{
res += i.ToString();
strChanged(res);
}
return res;
}
注意:SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str) 是将textBox1.Text设置为str的函数(用于避免跨线程异常)。
当您按下按钮 1 时,this.Text 将立即设置为 write() 函数的结果(“012345”)。
返回的字符串是 res,它是在 write() 内部构建的,从一个空字符串开始,并迭代地附加从 0 到 5 的数字。
创建字符串并为每个添加到 res 的数字时,将引发事件 strChanged 调用 updatestr 方法。
每次调用 updatestr 时都会创建一个线程并开始调用 updatethr。
这里 textBox1.Text 设置为 str (应该是渐进的 "", "0" , "01", "012", "0123", "01234", "012345")并在退出方法之前等待一秒钟.
使用 lock 语句,在 updatestr 中创建的线程应该在修改 textBox1.Text 之前等待前面的线程结束。
运行 这段代码我获得了 textBox1.Text 的值序列,这些值序列与预期序列不匹配,就好像线程没有按照它们在 updatestr 中创建的顺序启动。
为什么会这样?我该如何解决?提前致谢!
编辑:如果想尝试此代码,您可以将 SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str) 替换为 System.Windows.Forms.MessageBox.Show(str)
我相信您正在寻找不同的线程策略。看来您需要一个线程来维持秩序,这与完成操作的窗体主线程不同。通过使用 BlockingCollection,您可以按顺序让不同的线程对字符串进行操作。
我会这样重写代码:
event strHandler strChanged;
delegate void strHandler(string str);
public Form1()
{
InitializeComponent();
Thread th = new Thread(new ThreadStart(updatethr));
th.IsBackground = true;
th.Start();
strChanged += new strHandler(updatestr);
}
BlockingCollection<string> bc = new BlockingCollection<string>();
public void updatestr(string str)
{
bc.Add(str);
}
private void updatethr()
{
while(true)
{
string str = bc.Take();
SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str);
// Not sure why you need this here, other than simulating a long operation.
// Thread.Sleep(1000);
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Text = write();
}
private string write()
{
string res = "";
strChanged(res);
for (int i = 0; i <= 5; i++)
{
res += i.ToString();
strChanged(res);
}
return res;
}
我认为标题不言自明。只是我有一些 运行 随机顺序而不是我计划的顺序的线程。 这是示例代码:
event strHandler strChanged;
delegate void strHandler(string str);
public Form1()
{
InitializeComponent();
strChanged += new strHandler(updatestr);
}
public void updatestr(string str)
{
Thread th = new Thread(new ParameterizedThreadStart(updatethr));
th.IsBackground = true;
th.Start(str);
}
object obj = new object();
private void updatethr(object str)
{
lock (obj)
{
SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str);
Thread.Sleep(1000);
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Text = write();
}
private string write()
{
string res = "";
strChanged(res);
for (int i = 0; i <= 5; i++)
{
res += i.ToString();
strChanged(res);
}
return res;
}
注意:SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str) 是将textBox1.Text设置为str的函数(用于避免跨线程异常)。 当您按下按钮 1 时,this.Text 将立即设置为 write() 函数的结果(“012345”)。 返回的字符串是 res,它是在 write() 内部构建的,从一个空字符串开始,并迭代地附加从 0 到 5 的数字。 创建字符串并为每个添加到 res 的数字时,将引发事件 strChanged 调用 updatestr 方法。 每次调用 updatestr 时都会创建一个线程并开始调用 updatethr。 这里 textBox1.Text 设置为 str (应该是渐进的 "", "0" , "01", "012", "0123", "01234", "012345")并在退出方法之前等待一秒钟. 使用 lock 语句,在 updatestr 中创建的线程应该在修改 textBox1.Text 之前等待前面的线程结束。 运行 这段代码我获得了 textBox1.Text 的值序列,这些值序列与预期序列不匹配,就好像线程没有按照它们在 updatestr 中创建的顺序启动。 为什么会这样?我该如何解决?提前致谢!
编辑:如果想尝试此代码,您可以将 SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str) 替换为 System.Windows.Forms.MessageBox.Show(str)
我相信您正在寻找不同的线程策略。看来您需要一个线程来维持秩序,这与完成操作的窗体主线程不同。通过使用 BlockingCollection,您可以按顺序让不同的线程对字符串进行操作。
我会这样重写代码:
event strHandler strChanged;
delegate void strHandler(string str);
public Form1()
{
InitializeComponent();
Thread th = new Thread(new ThreadStart(updatethr));
th.IsBackground = true;
th.Start();
strChanged += new strHandler(updatestr);
}
BlockingCollection<string> bc = new BlockingCollection<string>();
public void updatestr(string str)
{
bc.Add(str);
}
private void updatethr()
{
while(true)
{
string str = bc.Take();
SystemUtilities.SetControlPropertyThreadSafe(textBox1, "Text", (string)str);
// Not sure why you need this here, other than simulating a long operation.
// Thread.Sleep(1000);
}
}
private void button1_Click(object sender, EventArgs e)
{
this.Text = write();
}
private string write()
{
string res = "";
strChanged(res);
for (int i = 0; i <= 5; i++)
{
res += i.ToString();
strChanged(res);
}
return res;
}