我的课程有什么问题?我无法将执行线程与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
答案 0 :(得分:4)
这是因为您将委托放在UI调度程序上,无论如何都会在UI线程上运行它(导致无响应的用户界面)。
您应该仅在UI调度程序上委派UI任务,其余部分可以在后台线程上运行。
答案 1 :(得分:0)
我认为单独的线程(无论是后台线程还是UI线程)无权访问主线程(ProgressChanged除外)。我花了很多时间在这个问题上,我找不到从辅助线程永久访问主线程的方法。
我的UI线程解决方案是使用WndProc与扩展(lParam)值和/或注册表值一起在线程之间进行聊天。
使用后台工作线程我通过指向主线程的窗口属性指针访问progress事件中的主线程。您只能从BgWorker中的ProgressChanged事件访问主线程。