简体   繁体   English

用户界面仍然使用backgroundWorker冻结

[英]UI still freezes using backgroundWorker

I'm quite new to WPF. 我对WPF很陌生。 I am developing a PRISM application and want to update the UI when an enumerable is updated. 我正在开发PRISM应用程序,并希望在更新枚举时更新UI。 I use a backgroundWorker in my modelView to update the enumaration. 我在modelView中使用backgroundWorker更新了枚举。 it all works fine until the enumeration it self gets updated and then the UI freezes!! 一切正常,直到它自身的枚举被更新,然后UI冻结! a friend told my I might be able to use the yield keyword but I didn't quite figured it out. 一位朋友告诉我,我也许可以使用yield关键字,但我不太清楚。

Here is the code: 这是代码:

public void ChangeCollection()
    {
        BackgroundWorker worker = new BackgroundWorker();

        // Set workers job
        worker.DoWork += (sender, e) =>
            {
                RunOnUIThread(() => IsBusy = true);
                e.Result = GetPrimes();
            };

        // On Complete
        worker.RunWorkerCompleted += (sender, e) =>
            {
                RunOnUIThread(() =>
                    {
                        IsBusy = false;

                        // HERE IS WHERE IT GETS STUCK
                        Numbers = new ObservableCollection<int>
                            ((IEnumerable<int>)e.Result);
                    });
            };

        // Start background operation
        worker.RunWorkerAsync();
    } 

    public ObservableCollection<int> Numbers 
    { 
        get {return _Numbers;} 
        set
        {
            _Numbers = value;
            RaisePropertyChanged(() => Numbers);
        }
    }

    public IEnumerable<int> GetPrimes()
    {
        List<int> primes = new List<int>();

        for (int i = 0; i < 100000; i++)
        {
            bool IsPrime = true;

            for (int j = 2; j < i; j++)
            {
                if (i % j == 0)
                    IsPrime = false;
            }

            if (IsPrime)
                primes.Add(i);
        }

        return primes;
    } 

Any advise would be greatly appriciated! 任何建议将不胜感激!

Thanks, Omri 谢谢Omri

yield won't help you here. yield不会在这里帮助您。 RunWorkerCompleted executes on the UI thread. RunWorkerCompleted在UI线程上执行。 Apparently instantiating the ObservableCollection<int> is taking a long time. 显然实例化ObservableCollection<int>花费很长时间。 The simplest solution may be to move the instantiation to the background thread ( DoWork ) as well. 最简单的解决方案可能是将实例也移动到后台线程( DoWork )。 It could also be a PropertyChanged event handler that is taking a long time, in which case it should also run on a background thread. 它也可能是花费很长时间的PropertyChanged事件处理程序,在这种情况下,它也应该在后台线程上运行。

A few things here. 这里有几件事。 1) Your worker and its delegates should be created when your object containing it is instantiated. 1)实例化包含它的对象时,应创建您的工作程序及其委托。

public class ViewModel 
{
    BackgroundWorker _primeWorker;

    public ViewModel()
    {
        _primeWorker = new BackgroundWorker;

        _primeWorker.DoWork += ...
    }

    public void AddSomeNumbers()
    {
         if(_primerWorker.IsBusy == false)
              _primeWorker.RunWorkerAsync();
    }
}

2) Your collection should be instantiated when the object containing it is instantiated to avoid a null exception being thrown should the object using this class calls the get . 2)当实例化包含它的对象时,应该实例化您的集合,以避免使用该类的对象调用get引发null异常。

3) Adding that many items would cause slowness due to each time you add a number an event is fired that the UI thread has to handle. 3)添加许多项会导致速度变慢,这是因为每次添加数字都会触发UI线程必须处理的事件。

This link has more info to help you out. 此链接有更多信息可以帮助您。 http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx http://msdn.microsoft.com/zh-CN/library/cc221403(v=vs.95).aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM