-6

我尝试在另一个线程上添加加载数据模型并将项目加载到列表框,因为将 50 个项目加载到列表框需要很长时间(大约 5 秒)。

我对 BackgroundWorker 有问题,它显示错误 Invalid cross-thread access

他是 Inbox.xaml 的代码

    public Inbox()
    {
        InitializeComponent();

        DataContext = App.ViewModel;
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        ProgressIndicator progress = new ProgressIndicator
        {
            IsVisible = true,
            IsIndeterminate = true,
            Text = "Načítání"
        };

        SystemTray.SetProgressIndicator(this, progress);
        SystemTray.IsVisible = true;

        BackgroundWorker backgroundWorker = new BackgroundWorker();
        backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
        backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);

        backgroundWorker.RunWorkerAsync();
    }

    private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        LoadData();
    }

    void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            MessageBox.Show(e.Error.Message);
        }
        else
        {
            SystemTray.IsVisible = false;
        }
    }

    private void LoadData()
    {
        try
        {
            (this.DataContext as MainViewModel).LoadInboxData();
        }
        finally
        {
            TasksListBox.ItemsSource = (this.DataContext as MainViewModel).Tasks;
        }
    }

我究竟做错了什么?

4

2 回答 2

2

BackgroundWorker.DoWork 处理程序在后台非 ui 线程上运行。在您的示例 LoadData() 方法在后台非 ui 线程上运行,并且您在该方法中设置 ListBox 的 ItemSource 属性。

您应该尝试将该代码移动到您的 BackgroundWorkder.RunWorkerCompleted 处理程序,因为此处理程序在 UI 线程上运行。

您的代码可以像下面这样重写以避免错误:

void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
        MessageBox.Show(e.Error.Message);
    }
    else
    {
        SystemTray.IsVisible = false;
    TasksListBox.ItemsSource = (this.DataContext as MainViewModel).Tasks;
    }
}

private void LoadData()
{
    (this.DataContext as MainViewModel).LoadInboxData();
}
于 2013-04-08T14:12:50.077 回答
1

您正在尝试从非 UI 线程更新 UI,因此您会遇到异常。

只有 UI 线程可以执行 UI 更新,您需要使用Dispatcher才能从非 UI 线程更新 UI。

Dispatcher.BeginInvoke(() =>
{
   // Update UI in here as this part will run on the UI thread.
});

请参阅:http: //msdn.microsoft.com/en-gb/library/system.windows.threading.dispatcher.begininvoke.aspx

于 2013-04-08T14:11:52.903 回答