-1

状況があります - コンソール アプリケーションが起動すると、3 つのスレッドが作成されます。これらのスレッドは永久にそこにとどまり、本来の処理を実行します。これらのスレッドのいずれかが、Windows フォームを別のスレッドとして表示できるようになるため、次のコードを使用して何かが返されるのを待ちません。

public void RunThread()
{
    Thread thread = new Thread(new ThreadStart(RunForm));
    thread.Name = "StatusForm";
    thread.Start();
}

public void RunForm()
{
    Application.Run(new StatusForm());
}

この Windows フォームは、3 つのスレッドすべてからいくつかの変数を取得しようとします。

int var1 = Manager1.InventoryEntriesOne
int var2 = Manager2.InventoryEntriesTwo
int var3 = Manager3.InventoryEntriesThree

最初のスレッドの InventoryEntries は次のように宣言されます (他の 2 つのスレッドも同様です)。

public static volatile InventoryEntries

何らかの理由で、ウィンドウフォームには、RunThread()関数を使用してウィンドウを表示したスレッドの変数のみが表示されます。たとえば、スレッド 1 がウィンドウを開始する場合、そのスレッドの変数のみが表示され、スレッド 2 と 3 の場合はすべて 0 になります。3 つのスレッドすべてから変数を読み取ることができる必要があり、どのスレッドでもかまいません。ウィンドウを立ち上げました。

ありがとうございました。

- - - - - - - - -編集 - - - - - - - - - -

コード内で何が起こっているかの簡単な例をお見せしましょう。これは Manager1 の例です。他の 2 人のマネージャーが基本的に同じことをしていると仮定します...

using System.Windows.Forms;
using System.Threading;

namespace Manager
{
    public class Manager1 : Manager
    {
        public static volatile int InventoryEntriesOne = 123;


        public override bool OnSomeEvent()
        {
            InventoryEntriesOne = 555;
        }

        public override bool OnSomeOtherEvent()
        {
            RunThread();
        }

        public void RunThread()
        {
            Thread thread = new Thread(new ThreadStart(RunForm));
            thread.Name = "StatusForm";
            thread.Start();
        }
        public void RunForm()
        {
            Application.Run(new StatusForm());
        }
    }
}

ご覧のとおり、Manager は Windows フォームを開いています。そのフォームで何が起こるかは次のとおりです。

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;

namespace Manager
{
    public partial class StatusForm : Form
    {
        Timer refreshTimer = new Timer();

        public StatusForm()
        {
            InitializeComponent();

            PlotData();

            refreshTimer.Interval = 5000;  //5 seconds in milliseconds  
            refreshTimer.Tick += new EventHandler(refreshTimer_Tick);
            refreshTimer.Start();
        }

        void refreshTimer_Tick(object sender, EventArgs e)
        {
            PlotData();
        }

        public void PlotData()
        {
            label1.Text = Manager1.InventoryEntriesOne.ToString();

            label2.Text = Manager2.InventoryEntriesTwo.ToString();

            label3.Text = Manager3.InventoryEntriesThree.ToString();
        }
    }
}

皆さんが今問題を理解してくれることを願っています。

4

2 に答える 2

1

ソリューションの別の組織を試してください。

  1. すべてのフォーム/ウィンドウとユーザーとのやり取りを管理する UI スレッドは 1 つだけです。
  2. 上記の UI スレッドを作成し (必要に応じて作成し)、作業をバックグラウンド スレッドに委任します。
  3. スレッドの起動が実際に測定可能なパフォーマンスの問題である場合 (私はこれを先験的に購入しませんが、発生する可能性があります)、Manager フォームの各インスタンスにプライベート バックグラウンド スレッドへの参照をキャッシュさせます。
  4. バックグラウンド スレッドが作業を完了し、割り当てられた Manager フォームを更新する必要がある場合は、Invoke()を使用します。
于 2013-08-16T19:08:04.593 に答える
0

Program.cs で InventoryEntries を定義する

于 2013-08-16T19:20:46.160 に答える