让我确保我理解你在做什么。您已经启动了 9 个线程,循环 6 次,每次更新一个文本框并休眠 1 秒。从它的声音来看,它们都在更新同一个标签。您评论说,如果您将更新推送到列表中,您将获得所有更新,我的猜测是所有 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();
}
我在 OnStartup 的覆盖中做了我的,因为在 VS2010 中,当您创建一个项目时,您的启动项将从 System.Windows.Application 继承。
我有这个简单的 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 个团队每秒更新一次。我有一些填充代码来模拟您拥有的对象:
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; }
}
}