cos*_*ost 9 c# wpf multithreading
我意识到我正在做的事情可能很愚蠢,但我正在学习WPF,并想知道如何做到这一点.
我有一个带有列表框的窗口.列表框用于在程序运行时传递有关程序的状态消息.例如"服务器启动""IP连接时的新连接"等.我希望在后台不断更新,所以我产生了一个新的线程来处理更新这个,但是当我调用添加项目时,我得到了错误消息"调用线程无法访问此对象,因为另一个线程拥有它."
知道如何从另一个线程更新列表框吗?或者在后台等
mar*_*mnl 25
如果您使用的是C#5和.NET 4.5或更高版本,则可以避免首先使用async
和获取另一个线程await
,例如:
private async Task<string> SimLongRunningProcessAsync()
{
await Task.Delay(2000);
return "Success";
}
private void Button_Click(object sender, RoutedEventArgs e)
{
button.Content = "Running...";
var result = await SimLongRunningProcessAsync();
button.Content = result;
}
Run Code Online (Sandbox Code Playgroud)
简单:
Dispatcher.BeginInvoke(new Action(delegate()
{
myListBox.Items.Add("new item"));
}));
Run Code Online (Sandbox Code Playgroud)
如果你在代码隐藏.否则,您可以使用以下命令访问Dispatcher(每个UIElement
)
Application.Current.MainWindow.Dispatcher.BeginInvoke(...
Run Code Online (Sandbox Code Playgroud)
好吧,在一行中有很多让我重复一遍:
当您想要更新UI控件时,正如消息所示,您必须从UI线程执行此操作.内置了将委托(方法)传递给UI线程的方法:Dispatcher
.一旦你的Dispatcher
,你可以Invoke()
的BeginInvoke()
传递代表要在UI线程上运行.唯一的区别是Invoke()
只有在委托运行后才会返回(即在你的情况下已经添加了ListBox的新项目),而是BeginInvoke()
立即返回,这样你调用的其他线程就可以继续(Dispatcher会尽快运行你的委托)无论如何,它可能会立即.)
我通过了一位匿名代表:
delegate() {myListBox.Items.Add("new item");}
Run Code Online (Sandbox Code Playgroud)
{}之间的位是方法块.这称为匿名,因为只创建了一个并且它没有名称(通常可以使用lambda表达式执行此操作,但在这种情况下,C#无法解析要调用的BeginInvoke()方法).或者我可以实例化一个委托:
Action myDelegate = new Action(UpdateListMethod);
void UpdateListMethod()
{
myListBox.Items.Add("new item");
}
Run Code Online (Sandbox Code Playgroud)
然后通过:
Dispatcher.Invoke(myDelegate);
Run Code Online (Sandbox Code Playgroud)
我还使用了Action类,它是一个内置的委托,但你可以创建自己的 - 你可以在MSDN上阅读更多关于委托的内容,因为这有点偏离主题..
您还可以使用具有匿名方法的Action委托来更新工作线程中的主线程.有关Action类的更多信息,请查看此处:
http://msdn.microsoft.com/en-us/library/018hxwa8.aspx
如果您想从多个点更新列表框,我建议明确设置委托,但是如果您只是希望通过单个调用在方法中的单个点更新线程,则可以按如下方式完成:
listbox.Dispatcher.BeginInvoke(new Action(delegate()
{
listbox.Items.Add(item); //where item is the item to be added and listbox is the control being updated.
}));
Run Code Online (Sandbox Code Playgroud)
请注意,我使用Action类,因为它封装了一个具有单个参数的方法(在本例中为listItem).
归档时间: |
|
查看次数: |
23047 次 |
最近记录: |