【问题标题】:C# Threading - an array of threads, where each thread contains a form with an imageC# Threading - 一个线程数组,其中每个线程包含一个带有图像的表单
【发布时间】:2011-11-23 09:40:18
【问题描述】:

我有一个由五个线程组成的数组。每个线程都包含相同的表单,每个表单都放在屏幕上的不同位置(仍在使用该方法:P)。

我试图让每个表单在其他表单完成放置之前加载其内容(图像)。目前这适用于第一种形式,但其他形式为空白或消失:P

最初每个表单都会被放置,但该方法需要在所有表单内容显示之前完成。

任何帮助将不胜感激,谢谢:)

public partial class TrollFrm : Form
{
    int number = 0;

    public TrollFrm()
    {
        InitializeComponent();

        startThreads();

    }

    private void TrollFrm_Load(object sender, EventArgs e)
    {

    }

    private void TrollFrm_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;
    }

    public void startThreads()
    {
        Thread[] ThreadArray = new Thread[5];

        for (int i = 0; i < 5; i++)
        {
            ThreadArray[i] = new Thread(new ThreadStart(createForm));

            ThreadArray[i].Start();
        }
    }

    public void createForm()
    {
        Form frm = new TrollChildFrm();

        Random randomX = new Random();

        Random randomY = new Random();

        number++;

        int xValue;

        int yValue;

        if (number % 2 == 0)    //number is even.
        {
            xValue = (Convert.ToInt32(randomX.Next(1, 1920))) + 200;

            yValue = (Convert.ToInt32(randomY.Next(1, 1080))) - 200;
        }

        else    //number is not even.
        {
            xValue = (Convert.ToInt32(randomX.Next(1, 1920))) - 200;

            yValue = (Convert.ToInt32(randomY.Next(1, 1080))) + 200;
        }

        frm.Show();

        frm.Location = new Point(xValue, yValue);

        Thread.Sleep(1000);
    }

【问题讨论】:

  • >这是你的鱼...

标签: c# arrays multithreading forms


【解决方案1】:

您的表单无法正确显示,因为它们没有在带有消息循环的线程上运行。一般规则是所有 UI 元素访问都必须发生在主 UI 线程上。

由于您已致电Thread.Sleep(1000),因此我假设您希望在每个表单的初始显示之间等待 1 秒。在这种情况下,我会使用System.Windows.Forms.TimerTick 事件将直接调用createForm。启用定时器,让 5 个Tick 事件通过,然后禁用定时器。我认为根本不需要创建任何线程。

【讨论】:

    【解决方案2】:

    您的表单不显示的原因是您在主 UI 线程上的一种方法中运行。相反,您可以创建一个生成新表单的方法,并以特定间隔在另一个线程上启动它(确保表单处理在主 UI 线程上完成)。所以你可以这样做:

    (Pseudo Code)
    private const int TIME_THRESHOLD = 100;
    
    int mElapsedTime = 0;
    Timer mTimer = new Timer();
    
    .ctor
    {
        mTimer.Elapsed += mTimer_Elapsed;
    }
    
    private void mTimer_Elapsed(...)
    {
        mElapsedTime++;
    
        if (mElapsedTime >= TIME_THRESHOLD)
        {
            mElapsedTime = 0;
    
            SpawnForm();
        }
    }
    
    private void SpawnForm()
    {
        // Make sure your running on the UI thread
        if (this.InvokeRequired)
        {
            this.BeginInvoke(new Action(SpawnForm));
            return;
        }
    
        // ... spawn the form ...
    }
    

    这只是我提议的一个示例 - 它在代码中看起来并不完全像这样,但这应该让您对执行步骤有所了解。

    【讨论】:

      【解决方案3】:

      我建议以这种方式使用 Thread.Sleep(1000)

      来电部分

          for (int i = 0; i < 5; i++)
          {
              ThreadArray[i] = new Thread(new ThreadStart(createForm));
              ThreadArray[i].Start();
          }
          Thread.Sleep(1000);
      

      也在为线​​程执行工作的方法中。

          while(!something)
          {
               Thread.Sleep(1000)
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多