gpt4 book ai didi

c# - 加入一个线程无一异常(exception)地停止执行

转载 作者:行者123 更新时间:2023-11-30 16:13:24 25 4
gpt4 key购买 nike

我的应用程序有 2 个线程 - 主 UI 线程和另一个线程。

应用程序在单独的线程上收集文件名列表。然后我希望这个列表显示在我的 GUI 中。该程序按预期工作,直到线程完成。它导致以下错误

"The calling thread must be STA, because many UI components require this."

运行以下代码,如您所见,它需要 2 个操作参数 - 一个用于 AddCurrentFile,一个称为 Complete。在 duplication.GetDuplicateList() 期间,它会调用 2 个方法。

        this._duplicatesThread = new Thread(() =>
{
try
{
duplication.GetDuplicateList(new Action<string>(AddCurrentFile), new Action<List<Duplicate>>(Complete));
CreateParent();
}
catch (Exception ex)
{
string s = ex.ToString();
throw;
}
});

AddCurrentFile 为我的属性提供一个值,并根据需要使用 INotifyProperty 我的 GUI 更新:

private void Complete(List<Duplicate> duplicateList)
{
this._duplicateList = duplicateList;
}

问题是当我调用 CreateParent() 时,因为这会创建一个新的 UserControl - 然后我得到 The calling thread must be STA, because many UI components require this. 但这发生在构造函数期间用户控件。以下代码是失败的地方

    private void CreateParent()
{
ObservableCollection<DuplicateControl> parent = new ObservableCollection<DuplicateControl>();

foreach (var duplicate in this._duplicateList)
{
DuplicateControl ic = new DuplicateControl();//This fails as soon as I enter the constructor. The DuplicateControl uses the UserControl as a base class
parent.Add(ic);
}
this.ParentDuplicate = parent;
}

因此,为了安抚线程,我在 CreateParent() 方法中添加了 this._duplicatesThread.Join;

但是,我认为(请纠正/同意我的看法)此时发生的事情是因为我在线程内加入,它有效地取消了非 UI 线程,因此在它的进程的那个点停止!因此,它永远不会执行 this._duplicatesThread.Join;

之后的行

现在,我希望这不是更好地问程序员,但是,我觉得这里的问题更多是我的设计而不是代码(尽管我很高兴知道模式和我的代码是垃圾呵呵)。

我的问题是,由于我无法通过新线程(因为它不是 UI 线程)执行此操作,我需要做什么?就好像我需要一个像 NewThread.FinishedExecuting += DoThisThing()

这样的委托(delegate)

最佳答案

您应该将 ViewModel 与 View (UI) 分开,并使用 WPF 数据绑定(bind)将它们绑定(bind)在一起。实际上可以从后台工作线程更新 ViewModel 对象,WPF 框架将自动编码 INotifyPropertyChanged.PropertyChanged数据绑定(bind) UI 控件的通知(至少在 .NET 4.5 中,AFAIK)。这样,控件将根据需要在主 UI 线程上自动更新。

但是,我宁愿以与 UI 元素相同的方式对待 ViewModel,即手动将所有 ViewModel 更新从后台线程编码到主 UI 线程。这可以通过 Dispatcher.Invoke 来完成(同步)或 Dispatcher.InvokeAsync (异步,推荐)。

也可以使用 Progress<T>模式将更新传播到 UI 线程。这是一个相关的问题/答案:

How to execute task in the wpf background while able to provide report and allow cancellation?

关于c# - 加入一个线程无一异常(exception)地停止执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21709440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com