Необходимо создать DependencySource в том же потоке, что и DependencyObject, используя await / async. - PullRequest
0 голосов
/ 07 января 2019

Я загружаю model3d в ModelLoader и указываю путь к TaskViewModel, используя конструкцию async / await.

Но у меня есть ошибка: «System.ArgumentException:« Необходимо создать DependencySource в том же потоке, что и DependencyObject ».

Как я могу это исправить. Модель должна быть загружена в другой поток.

AsyncDelegateCommand - работает с задачей

internal abstract class TaskViewModel : ViewModel
{
    private readonly AsyncDelegateCommand loadCommand;
    private readonly IModelLoader modelLoader;
    private Model3D model;

    public TaskViewModel(IModelLoader modelLoader)
    {
        this.modelLoader = modelLoader;
        loadCommand = new AsyncDelegateCommand(LoadAsync, () => CanLoad);
    }

    public ICommand LoadCommand => loadCommand;

    public bool CanLoad
    {
        get => canLoad;
        set => SetProperty(ref canLoad, value); // generate PropertyChanged
    }

    public Model3D Model
    {
        get => model;
        set => SetProperty(ref model, value);
    }

    private async Task LoadAsync()
    {
    string path = "somePath"
    Model3D model3D = await modelLoader.LoadAsync(path);
    Model = model3D;
    }
}

internal interface IModelLoader
{
    Task<Model3D> LoadAsync(string path);
}

internal sealed class ModelLoader : IModelLoader
{
    private readonly ModelImporter importer = new ModelImporter();
    private readonly Material material = new DiffuseMaterial(new SolidColorBrush(Colors.Beige));

    public ModelLoader()
    {
        importer.DefaultMaterial = material;
    }

    public Task<Model3D> LoadAsync(string path)
    {
        return Task.Factory.StartNew(() => Load(path), TaskCreationOptions.LongRunning);
    }

    private Model3D Load(string path)
    {
        return importer.Load(path);
    }
}

1 Ответ

0 голосов
/ 07 января 2019

Обычно вы не можете создать элемент управления в одном потоке, а затем взаимодействовать с ним друг с другом, но замороженная блокируемая переменная может быть разделена между потоками, поэтому вы можете попытаться заморозить Model3D перед тем, как его вернуть:

private Model3D Load(string path)
{
    var model = importer.Load(path);
    model.Freeze();
    return model;
}

Пожалуйста, обратитесь к MSDN для получения дополнительной информации о freezables.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...