UWP - 我无法从 UI 线程编辑 Application 类上的字段

Posted

技术标签:

【中文标题】UWP - 我无法从 UI 线程编辑 Application 类上的字段【英文标题】:UWP - I can't edit a field on the Application class from the UI thread 【发布时间】:2021-01-29 11:22:39 【问题描述】:

我的Application 类中有一个ObservableCollection<Element> 类型的属性Files

public sealed partial class App : Application

    public string CurrentPath;

    public ObservableCollection<Element> Files;

    public async void RefreshFilesAsync()
    
        Files.Clear();

        var folder = await StorageFolder.GetFolderFromPathAsync(CurrentPath);
        var foldersRequest = folder.GetFoldersAsync();
        var filesRequest = folder.GetFilesAsync();

        var folders = await foldersRequest;
        var files = await filesRequest;

        foreach (StorageFolder directory in folders)
        
            Files.Add(new FolderElement(directory));
        

        foreach (StorageFile file in files)
        
            Files.Add(new FileElement(file));
        
    

    // ...


Element 是我的 StorageFile 对象的包装类。创建此类以便为 Name 属性设置新值调用 API 以重命名实际文件。

public class Element

    public string Name
    
        get => StorageFile.Name;
        set =>
        
            StorageFolder.RenameAsync(value, NameCollisionOption.GenerateUniqueName).Completed = (IAsyncAction act, AsyncStatus status) =>
            
                (App.Current as App).RefreshFilesAsync();
            ;
        
    

    public StorageFile StorageFile  get; 

    //...


我有一个DataGrid 链接到应用程序属性Files,因此您可以推断,每当我为文件名重命名列时,都会调用API 来执行真正的重命名。

这是我的问题发生的时候。 API调用成功,文件被重命名,但是在RefreshFilesAsync()内部,当Files.Clear();被调用时,我得到一个异常The application called an interface that was marshalled for a different thread

我做错了什么?

【问题讨论】:

您正在从 Lamba 内部调用异步 void 方法。那就是把它扔回线程池。使您从应用程序调用的方法成为常规方法。或者至少使用调度程序返回到 Files.Clear 的窗口线程 我没有看到你现在在任何地方使用调度程序。 是的,很抱歉,我弄错了文件,我在另一个文件中使用调度程序,看起来很像这个文件。我修复了最初的帖子并为未来的读者添加了解决方案。无论如何,谢谢。 【参考方案1】:

为了使用 UI 线程运行代码,我使用了Window.Current.Dispatcher.RunAsync(),并将其放在单独的异步方法中。该异常不再出现。

public string Name

    get => StorageFolder.Name;
    set => RenameAsync(value);


private async void RenameAsync(string newName)

    await StorageFolder.RenameAsync(newName, NameCollisionOption.GenerateUniqueName);
    await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => (App.Current as App).RefreshFilesAsync());

【讨论】:

以上是关于UWP - 我无法从 UI 线程编辑 Application 类上的字段的主要内容,如果未能解决你的问题,请参考以下文章

UWP开发入门(二十一)——保持Ui线程处于响应状态

Xamarin.UWP应用程序无法启动,因为无法加载“Microsoft.Graphics.Canvas.UI.Xaml.CanvasImageSource”

UWP 从 Task 更新 UI

创建 UWP 应用 MS-Teams,如左窗格/选项卡 UI 控件

win2d图片平铺无法在UWP Scrollviewer中运行

从 JavaFX 中的不同线程更新 UI