gpt4 book ai didi

WPF Dispatcher 不像 BGWorker 那样工作

转载 作者:行者123 更新时间:2023-12-03 10:49:50 25 4
gpt4 key购买 nike

我在一个 MVVM 应用程序中。在这里,我有一个集合(ObservableCollection),它可能具有从不同线程完成的添加、删除操作。
这是代码。我试图让它尽可能完整:

private Thread _thread = null;
private Dispatcher _UIDispatcher = null;
public ObservableCollection<string> ListOfStrings { get; private set; }

Actor :
 public MainWindowViewModel(Dispatcher dispatcher)
{
this.ListOfStrings = new ObservableCollection<string>();
this.StartAsyncCall = new RelayCommand(AsyncCall, CanCallAsynch);
this._UIDispatcher = dispatcher;
}

我将 View 的调度程序作为引用(虽然这不是一个好习惯,因为它使单元测试变得困难。Gary Hall 提出了一种使用 AOP 的好方法。不过我可以在以后随时更改它。)。然后我通过命令调用的这个方法
private void AsyncCall()
{
if (this.ListOfStrings.Count > 0)
this.ListOfStrings.Clear();
//_backgroundWorker.RunWorkerAsync();
this._thread = new Thread(new ThreadStart(AddNumbersToList));
this._thread.IsBackground = true;
this._thread.Start();
}
private void AddNumbersToList()
{
Action delAddNum = new Action(AddNumbersToList);
for (int i = 0; i < 100000000; i++)
{
if (null != this._UIDispatcher &&
!this._UIDispatcher.CheckAccess())
_UIDispatcher.Invoke(DispatcherPriority.Render,delAddNum);
else
{
this.ListOfStrings.Add(Convert.ToString(i.ToString()));
}
}
}

ObservableCollection 绑定(bind)到 View 中的列表框。

我预期的效果是,随着 ObservableCollection 添加了新数字,它们应该显示在 UI 中。用户界面也将是 nicley 响应式的。但奇怪的是用户界面没有响应。当我试图通过后台工作人员实现时,同样的事情也很好地实现了。有人可以指出我哪里出错了。我不想选择后台工作人员,因为我想要使用更细粒度的 Thread 类的灵 active 。
下面是我与 BGWorker 一起使用的代码,它运行良好:
    private BackgroundWorker _backgroundWorker = new BackgroundWorker();

CTOR:
public MainWindowViewModel()
{
this.ListOfStrings = new ObservableCollection<string>();
this.StartAsyncCall = new RelayCommand(AsyncCall, CanCallAsynch);
_backgroundWorker.DoWork += AddNumbersToList;
_backgroundWorker.RunWorkerCompleted += this.LoadResultsCompleted;
_backgroundWorker.WorkerReportsProgress = true;
_backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(_backgroundWorker_ProgressChanged);
}

方法:
 private void AsyncCall()
{
if (this.ListOfStrings.Count > 0)
this.ListOfStrings.Clear();
this._backgroundWorker.RunWorkerAsync();
}

private void AddNumbersToList(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = sender as BackgroundWorker;
if(null!=bw)
for (int i = 0; i < 10; i++)
{
bw.ReportProgress(0, i);
Thread.Sleep(1000);
}
}


private void LoadResultsCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error == null)
{
this.ListOfStrings.Add("Completed");
CommandManager.InvalidateRequerySuggested();
}
}

//This works just wonderful:
void _backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.ListOfStrings.Add(Convert.ToString(e.UserState.ToString()));
}

先感谢您。

..詹姆士

最佳答案

它是挂起你的代码的递归......

这对我有用...

    private void AsyncCall()
{
if (this.MyCollection.Count > 0)
this.MyCollection.Clear();

this._thread = new Thread(new ThreadStart(AddNumbersToList));
this._thread.IsBackground = true;

this._thread.Start();
}

private void AddNumbersToList()
{
for (int i = 0; i < 100000000; i++)
{
this.Dispatcher.Invoke(
new Action(
delegate
{
this.MyCollection.Add(Convert.ToString(i.ToString()));
}));

Thread.Sleep(100);
}
}

关于WPF Dispatcher 不像 BGWorker 那样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8600823/

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