WPF,STA线程异常

本文关键字:异常 线程 STA WPF | 更新日期: 2023-09-27 18:01:08

我正在开发一个WPF(MVVM(应用程序。使用两个按钮,一个用于从数据库加载数据,另一个用于删除所选项目。单击Load按钮时,会触发LoadCommand并调用StartLoadingThread

private void StartLoadingThread()
{
    ShowLoadProcessing(); // show some text on top of screen ("Loading in progress...")
    ThreadStart ts = delegate
    {
        LoadMyitems();
        System.Windows.Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (EventHandler)
        delegate
        {
            HideLoadProcessing(); // hide the text "Loading in progress..."
        }, null, null);
    };
    ts.BeginInvoke(ts.EndInvoke, null);
}

工作正常,现在当我选择一个项目并单击Delete按钮时,DeleteItemCommand被触发并调用StartDeletingThread

private void StartDeletingThread()
{
    ShowDeleteProcessing(); // Show on top of screen "Deleting in progress..."
    ThreadStart ts = delegate
    {
        DeleteSelectedItem();
        System.Windows.Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (EventHandler)
        delegate
        {
            HideDeletingProcessing();
        }, null, null);
    };
    ts.BeginInvoke(ts.EndInvoke, null);
}

StartDeletingThread启动时,我得到以下异常:

{"The calling thread must be STA, because many UI components require this."}

WPF,STA线程异常

我想你想要这样的东西,尽管我对WPF有点新手,但你必须用WPF(Dispatcher(中相同的东西来替换this.BeginInvoke。此外,代码可能不会编译(为Thread添加Action类型转换?(,但想法是简单地启动线程(出于某些原因,您调用它,为什么?(,并在删除后在该线程中调用UI操作。

private void StartDeletingThread()
{
    ShowDeleteProcessing(); // Show on top of screen "Deleting in progress..."
    new Thread(() =>
    {
        DeleteSelectedItem();
        this.BeginInvoke(() => HideDeletingProcessing());
    }.Start();
}

尝试使用应用程序调度器调用StartDeletingThread,如下所示:

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,new       
Action(()=>StartDeletingThread())
private void StartDeletingThread()
{
    ShowDeleteProcessing(); // Show on top of screen "Deleting in progress..."
    Task.Run(() =>
    {
        DeleteSelectedItem();
        Application.Current.Dispatcher.BeginInvoke((Action)HideDeletingProcessing);
    });
}

可能会在CCD_ 10爆炸。我知道我们都喜欢为耗时不到一秒的动作显示进度条,但当它在StackOverflow上引发问题时,为什么还要麻烦呢?

private void StartDeletingThread()
{
    DeleteSelectedItem();
}

完成了,完成了。我非常怀疑删除所选项目需要很长时间。

如果在极少数情况下。。。然后您需要在DeleteSelectedItem中找到UI被触摸的位置,并使用应用程序的调度器进行触摸。

(附带说明,以下是如何在4.5中使用async/await安全地进行多线程处理……只要您了解async void的影响,即

private async void StartDeletingThread()
{
    // we're in the UI thread
    ShowDeleteProcessing();
    await DeleteSelectedItem();
    // back in the UI thread
    HideDeletingProcessing();
}
private Task DeleteSelectedItem()
{
    // doing the work on a Task thread
    return Task.Run(() => DeleteSelectedItem = null);
}