Nighteen_r 2023-01-13 16:59 采纳率: 60%
浏览 35
已结题

求指导,c#数据排列使用多线程后输出结果异常

求指导,问题如下。如下,我设计了一个冒泡排序法的数字排序功能,原本我将算法放在主线程内,代码运行良好。而我在修改后,将算法分别单独装入子线程中,输出结果出现了异常。
我个人认为可能是因为子线程在同时调用主线程的局部变量时出现了冲突,当然也有可能不是这个问题。希望有人能为我指点一下问题所在,在不改变多线程,不改变使用冒泡排序法的前提下指导下该如何解决。

功能:按下“排序”,主线程生成数据,两个子线程分别执行正反排序,并将结果输出在窗体上。
问题:使用子线程排序,输出结果异常。

源码放上:

namespace 数据统计_窗体
{

public partial class From1 : Form
{
    public From1()
    {
        CheckForIllegalCrossThreadCalls = false;
        InitializeComponent();
    }

    //TimeSpan ts = new TimeSpan();



    //int[] a = new int[n];

    Thread th = null;

    private void From1_Load(object sender, EventArgs e)
    {

    }

    private void buttonList_Click(object sender, EventArgs e)
    {
        if (th == null)
        {
            th = new Thread(PaiXu);
            th.IsBackground = true;//设置为后台线程
            th.Start();   //子线程开始执行方法
        }
        
    }

    private void buttonExit_Click(object sender, EventArgs e)
    {
        Close();
    }

    private void textBoxWrite_KeyPress(object sender, KeyPressEventArgs e)
    {
        if(((int)e.KeyChar <48||(int)e.KeyChar >57&&(int)e.KeyChar !=8))
        {
            MessageBox.Show("只能输入整数", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            e.Handled = true;
        }
    }

    private void PaiXu()
    {
        TimeSpan ts = new TimeSpan();


        

        int n = 0;
        

        //int[] arrayWaitSort = new int[n];
        n = int.Parse("0" + this.textBoxWrite.Text);

        int[] nums = new int[n];     //数组arr    nums用于储存生成的数据
        
        
        


        Random rnd = new Random();    //random随机数

        
            for (int i = 0; i < n; i++)       //i赋予初值0,只要i小于定义的总容量n,就会一直生成新的随机数
                nums[i] = rnd.Next();

        
       

        foreach (int everynum in nums)
        {
            this.textBoxNum.Text += everynum + "\r\n";
        }



        DateTime dt1 = DateTime.Now;


        Thread t2 = new Thread(() =>
        {
            int on = nums.Length;
            for (int i = 0; i < on-1 ; i++)
            {
                for (int j = 0; j < on -1- i; j++)
                {
                    if (nums[j] > nums[j + 1])
                    {
                        int temp = nums[j];
                        nums[j] = nums[j + 1];
                        nums[j+1] = temp;

                    }
                }
            }

            for (int i = 0; i < nums.Length; i++)

                this.textBoxListON.Text += nums[i] + "\r\n";
        });
        



        
        Thread t3 = new Thread(() =>
        {
            int otto = nums.Length - 1;
            for (int h = 0; h < otto; h++)
            {
                for (int k = 0; k < otto - h; k++)
                {
                    if (nums[k + 1] > nums[k])
                    {
                        int max = nums[k];
                        nums[k] = nums[k + 1];
                        nums[k + 1] = max;
                    }
                }
            }

            

            for (int h = 0; h < n; h++)

                this.textBoxListOut.Text += nums[h] + "\r\n";
        });


        t2.Start();
        t3.Start();

        if(th.IsAlive)
        {
            DateTime dt2 = DateTime.Now;
            ts = dt2 - dt1;
            this.textBoxTime.Text = Convert.ToString(ts);
        }

        


        
        
    }



}

}

界面如下:

img

接下来是调试效果:(排序结果输出异常)

img

  • 写回答

3条回答 默认 最新

  • wanghui0380 2023-01-13 17:55
    关注

    问题1:

    if(th.IsAlive)
            {
                DateTime dt2 = DateTime.Now;
                ts = dt2 - dt1;
                this.textBoxTime.Text = Convert.ToString(ts);
            }
    
    
    

    无效,因为t2,t3在线程里,你其实不知道他们的完成时间,所以这里是“假的执行时间”,修改方法。用异步信号量堵上,直到t2,t3完成
    当然如果你愿意使用task也行,await Task.WhenAll(Task1,task2)就好

    问题2:t2,t3升序,降序同时对nums操作。一个要升,一个要降,当然乱。所以你需要传参(线程传参),各个线程只用传参过来的而且最好是副本,而不是直接在原始数组上操作

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 1月24日
  • 已采纳回答 1月16日
  • 创建了问题 1月13日

悬赏问题

  • ¥15 用verilog实现tanh函数和softplus函数
  • ¥15 求京东批量付款能替代天诚
  • ¥15 slaris 系统断电后,重新开机后一直自动重启
  • ¥15 51寻迹小车定点寻迹
  • ¥15 谁能帮我看看这拒稿理由啥意思啊阿啊
  • ¥15 关于vue2中methods使用call修改this指向的问题
  • ¥15 idea自动补全键位冲突
  • ¥15 请教一下写代码,代码好难
  • ¥15 iis10中如何阻止别人网站重定向到我的网站
  • ¥15 滑块验证码移动速度不一致问题