在C#中以随机顺序运行的线程

时间:2015-01-02 03:42:14

标签: c# multithreading random

我认为标题不言自明。简单地说,我有一些以随机顺序运行的线程,而不是我计划的顺序。 这是一个示例代码:

    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,&#34; Text&#34;,(string)str)是一个将textBox1.Text设置为str的函数(用于避免跨线程异常)。 当你按下button1 this.Text将立即设置为write()函数的结果(&#34; 012345&#34;)。 返回的字符串是从空字符串开始在write()内部构建的res,并且迭代地附加从0到5的数字。 创建字符串并将每个数字添加到res时,将引发事件strChanged,调用updatestr方法。 每次调用updatestr时都会创建一个线程并开始调用updatethr。 这里textBox1.Text设置为str(应该逐步&#34;&#34;,&#34; 0&#34;,&#34; 01&#34;,&#34; 012&#34;,& #34; 0123&#34;,&#34; 01234&#34;,&#34; 012345&#34;)并在退出方法前等待一秒钟。 使用lock语句,updatestr中创建的线程应该在修改textBox1.Text之前等待前一个线程的结束。 运行此代码我获取textBox1.Text的值序列,这些值不匹配预期的序列,就像线程不按照在updatestr中创建的顺序开始一样。 为什么会这样?我该如何解决这个问题?提前谢谢!

编辑:如果想尝试此代码,您可以使用System.Windows.Forms.MessageBox.Show(str)

1 个答案:

答案 0 :(得分:1)

我相信您正在寻找不同的线程策略。看来你需要一个单独的线程来维护顺序,这与Form的主线程不同,以完成一个操作。通过使用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;
}