C# 从UI中分离线程

C# 从UI中分离线程,c#,wpf,multithreading,mvvm,dispatcher,C#,Wpf,Multithreading,Mvvm,Dispatcher,我的程序出了什么问题?我无法将执行线程与UI分离。线程执行期间无法访问UI 这是我的viewmodel: 第一种选择: // on button click: this.CreateImageList(); private void CreateImageList() { this.images.Clear(); ThreadStart threadStart = delegate { this.dispatcher.BeginInvoke(new T

我的程序出了什么问题?我无法将执行线程与UI分离。线程执行期间无法访问UI

这是我的viewmodel:

第一种选择:

// on button click:
this.CreateImageList();

private void CreateImageList()
{
    this.images.Clear();

    ThreadStart threadStart = delegate
    {
        this.dispatcher.BeginInvoke(new ThreadStart(delegate
        {
            foreach (var filePath in this.fileBuffer)
            {
                var result = new ImageObject(filePath);
                if (result.Image != null)
                {
                    this.images.Add(result);
                    this.dispatcher.Invoke(() => this.StatusText = filePath, DispatcherPriority.Render);
                }
            }

            this.RaisePropertyChanged("Images");
        }));
    };

    var thread = new Thread(threadStart);
    thread.IsBackground = true;
    thread.Start();
}
第二种选择:

// on button click:
this.CreateImageList();

private async void CreateImageList()
{
    await this.CreateImageListAsync();
}

private async Task CreateImageListAsync()
{
    this.images.Clear();
    var countTotal = this.fileBuffer.Count();
    var index = 0;

    await Task.Run(() => this.dispatcher.Invoke(
    (() =>
    {
        foreach (var filePath in this.fileBuffer)
        {
            var result = new ImageObject(filePath);
            if (result.Image != null)
            {
                this.images.Add(result);

                var percent = (index * 100) / countTotal;
                this.DoForce(() => this.StatusText = percent + "% " + filePath);
            }

            index++;
        }

        this.RaisePropertyChanged("Images");
    }), DispatcherPriority.SystemIdle));
}

public void DoForce(Action action)
{
    this.dispatcher.Invoke(DispatcherPriority.Render, action);
}

在第一个选项和第二个选项中,程序可以工作。但在第一个和第二个选项中,用户无法访问UI,这是因为您将委托放在UI调度程序上,该调度程序无论如何都会在UI线程上运行它(导致UI没有响应)


您应该在UI调度程序上只委派UI任务,rest可以在后台线程上运行。

这是因为您将委派放在UI调度程序上,而UI调度程序无论如何都会在UI线程上运行它(导致UI没有响应)


您应该在UI dispatcher上只委派UI任务,rest可以在后台线程上运行。

我的印象是,单独的线程,无论是后台线程还是UI线程,都无权访问主线程(ProgressChanged除外)。我在这个问题上花了很多时间,但我找不到从辅助线程永久访问主线程的方法

我的UI线程解决方案是使用WndProc在线程之间与扩展(lParam)值和/或注册表值进行聊天


对于后台工作线程,我通过指向主线程的窗口属性指针访问了progress事件中的主线程。您只能从BgWorker中的ProgressChanged事件访问主线程。

我的印象是,单独的线程,无论是后台线程还是UI线程,都无权访问主线程(ProgressChanged除外)。我在这个问题上花了很多时间,但我找不到从辅助线程永久访问主线程的方法

我的UI线程解决方案是使用WndProc在线程之间与扩展(lParam)值和/或注册表值进行聊天


对于后台工作线程,我通过指向主线程的窗口属性指针访问了progress事件中的主线程。您只能从BgWorker中的ProgressChanged事件访问主线程。

您会遇到哪些错误,或者“无法访问”是如何显示的?请提供准确的故障观察,而不是对您所看到的进行解释!这是因为您将委托放在UI调度程序本身上,而UI调度程序本身又将委托放回UI线程上。您应该只在UI调度程序上委派UI任务,rest可以在后台线程上运行。没有错误!程序运行良好!但我不能移动窗口,也不能点击任何按钮等等…Rohit Vats,谢谢!这肯定是解决方案,您不应该手动运行线程。如果您运行旧的Visual Studio(2013年以前)版本,最好使用异步/等待模式,或者仅使用
任务
类型。您会遇到哪些错误,或者“无法访问”是如何显示的?请提供准确的故障观察,而不是对您所看到的进行解释!这是因为您将委托放在UI调度程序本身上,而UI调度程序本身又将委托放回UI线程上。您应该只在UI调度程序上委派UI任务,rest可以在后台线程上运行。没有错误!程序运行良好!但我不能移动窗口,也不能点击任何按钮等等…Rohit Vats,谢谢!这肯定是解决方案,您不应该手动运行线程。如果运行旧的Visual Studio(2013年以前)版本,最好使用async/await模式,或者只使用
Task
type是的,就是这样。非常感谢。是的,就是这样。非常感谢。