繁体   English   中英

引起奇怪异常的异步方法

[英]Async Method Causing Strange Exception

我有绑定到ViewModel的WPF DataGrid ,一切都很好。 我现在意识到我需要将比最初预期更多的数据加载到DataGrid 因此,我已经使用async使该数据加载到Viewmodel容器中成为非UI阻止方式。 因此,在我的ResourceDataViewModel : ViewModelBase我有以下方法

public async void LoadResourceFilesAsync(string fullFileName = null)
{
    if (!String.IsNullOrEmpty(fullFileName))
        this.FullFileName = fullFileName;
    strategy = manager.InitialiseStrategy(this);
    if (strategy == null)
        return;

    ...

    // Get data asynchoniously.
    List<ResourceViewModel> resourceViewModelList = await strategy.LoadResourceFilesAsync();
    this.Resources = new TypedListObservableCollection<ResourceViewModel>(resourceViewModelList);

    // Setup event handlers.
    this.Resources.CollectionChanged += this.OnCollectionChanged;
    foreach (ResourceViewModel rvm in resourceViewModelList)
        rvm.PropertyChanged += this.OnResourceViewModelPropertyChanged;

    // Set the file name for View and ViewModel.
    this.FullFileName = strategy.FullFileName;
    base.DisplayName = Path.GetFileName(this.FullFileName); 

    ...
}

因此,在使装入方法async ,一切都很好。 数据已加载,并且绑定到TabItem标头属性的DisplayName (在abstract ViewModelBase类中定义的属性)导致文件名正确显示在TabItem标头中。 现在,我已经使加载异步,将数据加载到DataGrid与您从上述代码中所期望的一样,但是,

base.DisplayName = Path.GetFileName(this.FullFileName); 

不会更新base.DisplayName而是以静默方式 (即,在我的代码中不会抛出base.DisplayName )导致System.ArgumentException并显示以下消息:

Message =“无法在对象实例上找到方法。”

现在,我已将base.DisplayName更改为**this**.DisplayName ,这将停止异常,但仍不更新TabItem Header为什么会发生这种情况,我该如何解决?

注意。 我已经检查了要在其上执行的线程,并且按预期是MainThread / UIThread,这使得它异常。

更新。 当我使用this.DisplayName时,我已经使用Snoop来了解绑定的情况。绑定显示{DisconnectedItem} (我在MSDN上找到了一个相关的问题 )。 但是我仍然对这里发生的事情不知所措...


编辑地址注释

我的应用程序MainWindow的DataContextMainWindowViewModel 这包含一个属性

public ObservableCollection<WorkspaceViewModel> Workspaces { ... }

其中包含我想在每个TabItem显示的ViewModels。 我有另一个ViewModel(称为ResourceDataViewModel ) which holds the DataGrid s and inherits from定义为的公共WorkspaceViewModel`。

public abstract class WorkspaceViewModel : ViewModelBase { ... }

并处理所有MVVM内容,例如OnPropertyChanged处理程序等。在MainWindowViewModel ,将资源文件加载到主窗口中的TabControl中的调用层次结构是:

public void LoadResourceFiles(string fullFileName = null)
{
    // Build and load the ViewModel in to the View.
    ResourceDataViewModel workspace = new ResourceDataViewModel(this);
    workspace.LoadResourceFilesAsync(fullFileName);
    ...
}

ResourceDataViewModel我有上面原始问题中显示的方法。 然后,这会从策略工厂获取策略并异步加载数据-在这种情况下,请使用以下方法

public async Task<List<ResourceViewModel>> LoadResourceFilesAsync()
{
    // Do preliminary work here [build FileCultureDictionary etc.].
    ...

    // Build the resource data sets and return.
    List<Resource> buildResult = await BuildResourceDataAsync(FileCultureDictionary);
    return (from resource in buildResult
              select new ResourceViewModel(resource)).ToList();
}

private async Task<List<Resource>> BuildResourceDataAsync(Dictionary<string, string> cultureDict)
{
    // Now add the data.
    int fileIndex = 1;
    const int coreColumnIndex = 2;
    string[] strArr = null;
    List<string[]> strArrList = new List<string[]>();

    // Start building the data.
    Task<List<Resource>> task = Task.Factory.StartNew<List<Resource>>(() =>
        {
            // Do some work here...
            ...
            return resources;
        });
    return await task;
}

注意,从这些方法返回的数据很好。 这些方法本身似乎并不是导致上述问题的原因-但是可能是上下文切换。 我在这里真的很茫然,所以任何想法都欢迎。

您是否尝试过将UI中相关Binding对象上的Binding类的IsAsync属性设置为True 这为我解决了类似的问题。

我已经找到了解决此问题的方法,但是我不认为这是最好的方法,更多的是解决方法。 在ViewModel中,我尝试使用

base.DisplayName = "XYZ";

这是行不通的。 交换thisbase在上面防止异常,但我仍然有异常( WPF库的错误这是我觉得这个问题的原因)。 现在,要解决DataContext开关,我在ViewModelBaseResourceDataViewModel覆盖了DisplayName

public override string DisplayName
{
    get { return base.DisplayName; }
    protected set
    {
        if (base.DisplayName == value)
            return;
        base.DisplayName = value;
        OnPropertyChanged("DisplayName");
    }
}

这似乎可以停止绑定问题,但会稍稍延迟DisplayNameTabItem上的显示。

我欢迎任何其他人提供的其他解决方案,希望这对其他人有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM