如何使用C#在另一个线程中使用参数运行过程

本文关键字:参数 运行 过程 线程 何使用 另一个 | 更新日期: 2023-09-27 18:00:06

我一直在尝试调用一个过程并在C#中的新线程中使用一些参数。这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace Random_colored_rectangles
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        Thread th;
        Random rand;
        System.Drawing.Color[] colors = new System.Drawing.Color[5] {Color.Orange, Color.Red, Color.Pink, Color.Black, Color.Gold };
        private void DrawColor(Color color)
        {
            for (int i = 0; i < 100; i++)
            {
                DrawRectangle(color, 3 , rand.Next(0, this.Width), rand.Next(0, this.Height), 10, 10);
                Thread.Sleep(100);
            }
            MessageBox.Show(color + " done");
        }
        private void DrawRectangle(Color barva, float width, int pos_x, int pos_y, int size_x, int size_y)
        {
            Pen myPen = new Pen(barva, width);
            Graphics formGraphics;
            formGraphics = plocha.CreateGraphics();
            formGraphics.DrawRectangle(myPen, new Rectangle(pos_x, pos_y, size_x, size_y));
            myPen.Dispose();
            formGraphics.Dispose();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            rand = new Random();
        }
        private void Form1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.R)
            {
                th = new Thread(DrawColor);
                th.Name = Convert.ToString(threadCount);
                threadList.Add(th);
                threadCount = threadCount + 1;
                th.Start(colors[rand.Next(0, colors.Length)]);
            }
        }
    }
}

这个代码应该(在按下R之后)制作100个随机的彩色矩形(颜色是从少数颜色的数组中选择的)。但是,我无法让我的线程用随机颜色选择的参数启动过程DrawColor

你能帮帮我吗?

如何使用C#在另一个线程中使用参数运行过程

您可以使用Task来完成此操作。

Color theColorToPass = someColor;
Task.Factory.StartNew(color => {
  DrawColor(color);
}, theColorToPass);

不过,您也可以直接从Task中访问数组。我认为把它传给线程没有意义。

根据那些更熟悉C#的注意事项的人的建议(这不是我试图听起来刻薄或其他什么),我设计了一种不需要CreateGraphics()Thread.Sleep()就能实现您想要的东西的方法。不幸的是,这会在命中e.Graphics.DrawRectangle(penToUse, rectanglesToUse[0]);时抛出OutOfMemoryException。这是什么意思?

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace Colors
{
    public partial class Form1 : Form
    {
        Timer timer = new Timer { Interval = 100 };
        Random rand = new Random();
        Color[] colors = new Color[5]
        {
            Color.Black,
            Color.Blue,
            Color.Green,
            Color.Purple,
            Color.Red
        };
        List<Pen> usedPens = new List<Pen>();
        List<Rectangle> usedRectangles = new List<Rectangle>();
        Pen penToUse;
        List<Rectangle> rectanglesToUse = new List<Rectangle>();
        public Form1()
        {
            InitializeComponent();
        }
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                penToUse = new Pen(GetRandomColor(), 3);
                rectanglesToUse.Clear();
                for (int i = 0; i < 100; i++)
                    rectanglesToUse.Add(GetRandomRectangle());
                this.Refresh();
            }
        }
        private Color GetRandomColor()
        {
            return colors[rand.Next(0, colors.Length)];
        }
        private Rectangle GetRandomRectangle()
        {
            return new Rectangle(rand.Next(0, Width), rand.Next(0, Height), 10, 10);
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            for (int i = 0; i < usedRectangles.Count; i++)
                e.Graphics.DrawRectangle(usedPens[i % 100], usedRectangles[i]);
            timer.Tick += delegate
            {
                if (rectanglesToUse.Count > 0)
                {
                    e.Graphics.DrawRectangle(penToUse, rectanglesToUse[0]);
                    usedRectangles.Add(rectanglesToUse[0]);
                    rectanglesToUse.RemoveAt(0);
                }
                else
                {
                    usedPens.Add(penToUse);
                    timer.Stop();
                }
            };
            timer.Start();
        }
    }
}