我想从我的后台工作人员访问GUI上的列表框中的选择。没有任何其他更改尝试这样做会抛出此错误
Cross-thread Operation Not Valid: Control '_ListBox1' accessed from a thread other than the thread it was created on
我看到避免这种情况的选项是通过以下语法使用Invoke
,但.Net 4
(或更高)是否可以接受?
var selectedItems = (IList)this.Invoke(new Func<IList>(() => Listbox1.SelectedItems.Cast<object>().ToList()));
为了更清晰的图片,这就是我想从我的backgroundworker访问列表框项目的方式
namespace clown
{
public partial class Form1 : Form1
{
public Form1()
{
ListBox1.Items.Add("Firefly");
ListBox1.Items.Add("Hellfire");
}
private void btn1234_Click()
{
backgroundworker1.RunWorkerAsync();
}
private void backgroundworker1_DoWork(object sender, DoWorkEventArgs e)
{
//Long Running Process taking place here
//then we hit this
if (ListBox1.SelectedItems.Contains("Firefly")) { //take this course }
if (ListBox1.SelectedItems.Contains("Hellfire)) { //take this course }
}
}
}
答案 0 :(得分:6)
fun isTrue (n,tup) =
if #2 (tup) then true
else false;
Invoke
事件处理程序中的 Backgroundworker's
。您应该考虑使用DoWork
Backgroundworker's
或ProgressChanged
事件。
请参阅MSDN Help Here。
请参阅本文的第一个注释:
您必须小心不要操纵任何用户界面对象 你的DoWork事件处理程序。而是与用户界面进行通信 通过ProgressChanged和RunWorkerCompleted事件。
如果您实际发布了更多代码,可能会给出更全面的答案。
修改1:更多代码
由于OP更新了他的帖子以包含更多代码,我也做了同样的事情。
RunWorkerCompleted
答案 1 :(得分:0)
这是“可接受的”,但现在不是一个好习惯。 BackgroundWorker被认为是过时的,应该使用带异步/等待的任务。
下面是一个示例,说明如何实现一个方法在另一个线程上执行某些操作,保持UI响应并在执行完成后更新UI(使用WPF和MVVM模式):
public class ViewModel : INotifyPropertyChanged
{
...
public string PathInfo { ... } // raises INotifyPropertyChanged.PropertyChanged event from the setter
public RelayCommand ProcessPathsCommand { get; set; }
public ViewModel()
{
ProcessPathsCommand = new RelayCommand(ProcessPaths);
}
public async void ProcessPaths()
{
// disable the command, which will lead to disabling a button bound to the command
ProcessPathsCommand.IsEnabled = false;
try
{
string result = null;
// run processing on another thread
await Task.Run(() =>
{
// emulate hard-work
Thread.Sleep(5000);
result = "Here are the results: bla bla bla";
});
// update the property on the view model, which will lead to updating a textblock bound to this property
// thanks to the "await" keyword, this line of code will be executed only when the task finishes
// and it will be executed on UI thread
PathInfo = result;
}
finally
{
ProcessPathsCommand.IsEnabled = true;
}
}
如果您需要更多详细信息,请随时与我们联系。