あなたが何をしているのか、私が理解していることを確認させてください。テキスト ボックスを更新して 1 秒間スリープするたびに、6 回ループする 9 つのスレッドを開始しました。その音から、彼らはすべて同じレーベルを更新しています。更新をリストにプッシュすると、すべてを取得できるとコメントしましたが、私の推測では、9 つのスレッドすべてが非常に高速に更新されているため、それを見ることができず、最後のスレッドが優先されます。
UI をどのように構築しているかはわかりませんが、これは WPF と MVVM(Model-View-ViewModel) に最適だと思います。よほどの理由がない限り、私は WinForms を使用しません。WPF の方がはるかに簡単に操作できます。
いくつかのビュー モデルを作成します。
public class MainWindowViewModel : DispatcherObject, INotifyPropertyChanged
{
public MainWindowViewModel()
{
Matches = new ObservableCollection<MatchViewModel>();
}
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<MatchViewModel> _matches;
public ObservableCollection<MatchViewModel> Matches
{
get { return _matches; }
set
{
_matches = value;
OnPropertyChanged("Matches");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class MatchViewModel : DispatcherObject, INotifyPropertyChanged
{
public MatchViewModel()
{
HomeTeam = new TeamViewModel();
AwayTeam = new TeamViewModel();
}
public event PropertyChangedEventHandler PropertyChanged;
private TeamViewModel _homeTeam;
public TeamViewModel HomeTeam
{
get { return _homeTeam; }
set
{
_homeTeam = value;
OnPropertyChanged("HomeTeam");
}
}
private TeamViewModel _awayTeam;
public TeamViewModel AwayTeam
{
get { return _awayTeam; }
set
{
_awayTeam = value;
OnPropertyChanged("AwayTeam");
}
}
public void PlayMatch()
{
for (int i = 0; i < 6; i++)
{
if (i % 2 == 0)
OnGoalScored(HomeTeam);
else
OnGoalScored(AwayTeam);
Thread.Sleep(1000);
}
}
private void OnGoalScored(TeamViewModel team)
{
if (!team.Dispatcher.CheckAccess())
{
team.Dispatcher.Invoke((Action<TeamViewModel>)OnGoalScored, team);
}
else
{
team.Score++; // do other stuff here
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class TeamViewModel : DispatcherObject, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
private int _score;
public int Score
{
get { return _score; }
set
{
_score = value;
OnPropertyChanged("Score");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
次に、UI スレッドのプログラム クラスで、次のようにします。
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
MainWindowViewModel mainWindow = new MainWindowViewModel();
List<Thread> matchThreads = new List<Thread>();
foreach (Team[] opponents in Program.cm.nextMatches)
{
MatchViewModel match = new MatchViewModel();
match.HomeTeam.Name = opponents[0].Name;
match.AwayTeam.Name = opponents[1].Name;
mainWindow.Matches.Add(match);
Thread matchThread = new Thread(match.PlayMatch);
matchThreads.Add(matchThread);
matchThread.Start();
}
MainWindow = new MainWindow();
MainWindow.DataContext = mainWindow;
MainWindow.Show();
}
VS2010 では、プロジェクトを作成するときにスターアップ項目が System.Windows.Application から継承されるため、OnStartup のオーバーライドで私が行いました。
テスト用にこのシンプルな UI があります。
<Window x:Class="TestMatch.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<ItemsControl ItemsSource="{Binding Matches}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1} - {2} {3}">
<Binding Path="HomeTeam.Name"/>
<Binding Path="HomeTeam.Score"/>
<Binding Path="AwayTeam.Name"/>
<Binding Path="AwayTeam.Score"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
このコードは非常に粗雑であり、これを行う MVVM の方法の簡単なデモを提供するために一緒に投げられます。9 チームすべてを 1 秒ごとに更新することができました。あなたが持っていたオブジェクトをシミュレートするためのフィラーコードがいくつかありました:
public partial class Program
{
protected override void OnStartup(StartupEventArgs e)
{
...
}
private class Team
{
public string Name { get; set; }
}
private static class cm
{
static cm()
{
nextMatches =
new Team[][]
{
new[] { new Team { Name = "TeamA" }, new Team { Name = "TeamB" }},
new[] { new Team { Name = "TeamC" }, new Team { Name = "TeamD" }},
new[] { new Team { Name = "TeamE" }, new Team { Name = "TeamF" }},
new[] { new Team { Name = "TeamG" }, new Team { Name = "TeamH" }},
new[] { new Team { Name = "TeamI" }, new Team { Name = "TeamJ" }},
new[] { new Team { Name = "TeamK" }, new Team { Name = "TeamL" }},
new[] { new Team { Name = "TeamM" }, new Team { Name = "TeamN" }},
new[] { new Team { Name = "TeamO" }, new Team { Name = "TeamP" }},
new[] { new Team { Name = "TeamQ" }, new Team { Name = "TeamR" }},
};
}
public static Team[][] nextMatches { get; set; }
}
}