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

C# 在C中以随机顺序运行的线程#,c#,multithreading,random,C#,Multithreading,Random,我认为这个标题不言而喻。简单地说,我有一些线程以随机顺序而不是我计划的顺序运行。 这是一个示例代码: event strHandler strChanged; delegate void strHandler(string str); public Form1() { InitializeComponent(); strChanged += new strHandler(updatestr); } public

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

    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;
    }
事件strHandler strchange;
委托void strHandler(字符串str);
公共表格1()
{
初始化组件();
strChanged+=新strHandler(updatestr);
}
公共void updatestr(字符串str)
{
Thread th=新线程(新的参数化ThreadStart(updatethr));
th.IsBackground=true;
启动(str);
}
object obj=新对象();
私有void updatehr(对象str)
{
锁(obj)
{
SetControlPropertyThreadSafe(textBox1,“Text”,(string)str);
睡眠(1000);
}
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
this.Text=write();
}
私有字符串写入()
{
字符串res=“”;
strChanged(res);

对于(int i=0;i我相信您正在寻找一种不同的线程策略。似乎您需要一个线程来维护顺序,这与表单的主线程完成操作不同。通过使用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;
}
事件strHandler strchange;
委托void strHandler(字符串str);
公共表格1()
{
初始化组件();
Thread th=新线程(new ThreadStart(updatethr));
th.IsBackground=true;
th.Start();
strChanged+=新strHandler(updatestr);
}
BlockingCollection bc=新BlockingCollection();
公共void updatestr(字符串str)
{
bc.Add(str);
}
私有void updatehr()
{
while(true)
{
string str=bc.Take();
SetControlPropertyThreadSafe(textBox1,“Text”,(string)str);
//除了模拟长时间的操作之外,我不知道为什么需要这个。
//睡眠(1000);
}
}
私有无效按钮1\u单击(对象发送者,事件参数e)
{
this.Text=write();
}
私有字符串写入()
{
字符串res=“”;
strChanged(res);

对于(int i=0;i)您假设,由于线程是按特定顺序启动的,因此它们以相同的顺序运行,并且该顺序是获取锁的顺序。这两个假设都不必为真。操作系统无法保证线程将按特定顺序调度。锁无法保证公平性in C#。我很确定线程是按照你启动它们的顺序开始的……但之后它们就开始比赛了。谁先到达终点线,谁就要第一个锁定并写入。这可能是第二匹“赛马”,也可能是第三匹“赛马”,最后你会得到一个有趣的结果,如“201345”。如果您确实需要它们以特定的顺序到达,那么您应该让这些代码在单个线程上运行。另一种选择是在前一个线程结束或即将结束后启动每个线程。但是我如何解决这个问题?为什么首先必须是多线程的?这最终会影响设计。如何无论如何,如果你真的必须这样做,你可能可以模拟TCP协议。设计时考虑到互联网的随机性,基本上每个发送出去的数据包都被分配了一个顺序号。当它出现在末尾时,该顺序号将用于以正确的顺序手动重新组装最终的消息。这只是我在另一个应用程序中遇到的一个问题示例是最短路径查找程序(与此类似)。我有一个函数,可以查找最短路径并将其作为点列表返回。对于检查的地图的每个节点,我希望更新地图预览,以逐步查看发生的情况(如链接中所示)。要做到这一点,我需要截获节点的每一次更改,更新地图,并在下一次更新之前等待几毫秒。太好了!非常感谢!