Backgroundworker 在第一次表达后退出
Backgroundworker exits after first expression
我有一个绑定到 ObservableCollection 的列表视图。有了它,我想用 WPF gui 模拟一个聊天应用程序。
为了模拟一些 activity 我想使用一个会发送一点垃圾邮件的后台工作人员。但是工作人员总是在执行完第一条语句后退出他的循环,所以我的问题是:他为什么这样做以及如何解决它?
这是到目前为止的代码:
public partial class MainWindow : Window, INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private string pCurrentUsername;
public string currentUsername
{
get { return pCurrentUsername; }
set
{
pCurrentUsername = value;
if (null != this.PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs("currentUsername"));
}
}
}
ObservableCollection<ChatPost> items = new ObservableCollection<ChatPost>();
BackgroundWorker bgWorker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
currentUsername = "Me";
items.Add(new ChatPost("this", "that"));
bgWorker.DoWork += new DoWorkEventHandler(mockBussiness);
bgWorker.RunWorkerAsync();
lvChat.ItemsSource = items;
}
private void mockBusiness(object o, DoWorkEventArgs args)
{
while (!bgWorker.CancellationPending)
{
items.Add(new ChatPost("guy1", "Ey man!"));
items.Add(new ChatPost("guy2", "What man?"));
}
}
private void btSend_Click(object sender, RoutedEventArgs e)
{
items.Add(new ChatPost(currentUsername, tbMessage.Text));
}
}
public class ChatPost
{
public ChatPost()
{ }
public ChatPost(string username, string message)
{
this.username = username;
this.message = message;
}
public string username { get; set; }
public string message { get; set; }
}
所以唯一被执行(意思是打印)的是一次"Ey man!"
是的,您正在非 UI 线程上修改 UI(通过 ObservableCollection<>
间接修改)。你不被允许那样做。我怀疑您应该找到抛出的异常以提供该详细信息,尽管可能不容易找到。
通常,您需要编组回 UI 线程以进行任何线程操作。如果您在 .NET 4.5 上使用 WPF,显然您可以为此使用 BindingOperations.EnableCollectionSynchronization
,但我承认我对此没有直接经验。
我有一个绑定到 ObservableCollection 的列表视图。有了它,我想用 WPF gui 模拟一个聊天应用程序。
为了模拟一些 activity 我想使用一个会发送一点垃圾邮件的后台工作人员。但是工作人员总是在执行完第一条语句后退出他的循环,所以我的问题是:他为什么这样做以及如何解决它?
这是到目前为止的代码:
public partial class MainWindow : Window, INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private string pCurrentUsername;
public string currentUsername
{
get { return pCurrentUsername; }
set
{
pCurrentUsername = value;
if (null != this.PropertyChanged)
{
PropertyChanged(this, new PropertyChangedEventArgs("currentUsername"));
}
}
}
ObservableCollection<ChatPost> items = new ObservableCollection<ChatPost>();
BackgroundWorker bgWorker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
currentUsername = "Me";
items.Add(new ChatPost("this", "that"));
bgWorker.DoWork += new DoWorkEventHandler(mockBussiness);
bgWorker.RunWorkerAsync();
lvChat.ItemsSource = items;
}
private void mockBusiness(object o, DoWorkEventArgs args)
{
while (!bgWorker.CancellationPending)
{
items.Add(new ChatPost("guy1", "Ey man!"));
items.Add(new ChatPost("guy2", "What man?"));
}
}
private void btSend_Click(object sender, RoutedEventArgs e)
{
items.Add(new ChatPost(currentUsername, tbMessage.Text));
}
}
public class ChatPost
{
public ChatPost()
{ }
public ChatPost(string username, string message)
{
this.username = username;
this.message = message;
}
public string username { get; set; }
public string message { get; set; }
}
所以唯一被执行(意思是打印)的是一次"Ey man!"
是的,您正在非 UI 线程上修改 UI(通过 ObservableCollection<>
间接修改)。你不被允许那样做。我怀疑您应该找到抛出的异常以提供该详细信息,尽管可能不容易找到。
通常,您需要编组回 UI 线程以进行任何线程操作。如果您在 .NET 4.5 上使用 WPF,显然您可以为此使用 BindingOperations.EnableCollectionSynchronization
,但我承认我对此没有直接经验。