Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在具有长时间运行进程的视图上使用MVVM_C#_Wpf_Silverlight_Mvvm - Fatal编程技术网

C# 在具有长时间运行进程的视图上使用MVVM

C# 在具有长时间运行进程的视图上使用MVVM,c#,wpf,silverlight,mvvm,C#,Wpf,Silverlight,Mvvm,我这里有一个例子,它复制了我试图实现的目标。 正如下面的代码所示-我有一个ViewModel,它更新绑定到视图的ObservableCollection属性。通常,我会根据从模型检索到的结果更新集合,但希望这个示例就足够了 using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.T

我这里有一个例子,它复制了我试图实现的目标。 正如下面的代码所示-我有一个ViewModel,它更新绑定到视图的ObservableCollection属性。通常,我会根据从模型检索到的结果更新集合,但希望这个示例就足够了

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Controls;

namespace MVVMWpf.ViewModel
{
    public class ListViewModel
    {

        public ObservableCollection<int> SomeObjectCollection { get; set; }

        public ListViewModel()
        {

            SomeObjectCollection = new ObservableCollection<int>();

        }

        public void Do()
        {
             for (int i = 1; i < 1000000; i++)
             {
                 int i1 = i;
                 SomeObjectCollection.Add(i1);
             }
        }

    }
}
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.Linq;
使用系统文本;
使用系统线程;
使用System.Windows.Controls;
命名空间MVVMWpf.ViewModel
{
公共类ListViewModel
{
公共ObservableCollection SomeObjectCollection{get;set;}
公共ListViewModel()
{
SomeObjectCollection=新的ObservableCollection();
}
公营部门
{
对于(int i=1;i<1000000;i++)
{
int i1=i;
SomeObjectCollection.Add(i1);
}
}
}
}
不幸的是,这会阻塞此UI。它只会在循环运行到完成时更新视图。我解决它的方式打破了MVVM的概念。这就是为什么我需要你的帮助。我是这样做的

public class ListViewModel
{
    private delegate void LongRunningProcess();
    public ObservableCollection<int> SomeObjectCollection { get; set; }
    private ListBox listBox;
    public ListViewModel(ListBox listBox)
    {
        this.listBox = listBox;
        SomeObjectCollection = new ObservableCollection<int>();

    }

    public void Do()
    {
        Thread thread = new Thread(() =>
        {
           for (int i = 1; i < int.MaxValue; i++)
           {
               int i1 = i;
               listBox.Dispatcher.Invoke(
                   new LongRunningProcess(() =>
                   SomeObjectCollection.Add(i1);
                 }});

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }

}
公共类ListViewModel
{
私有委托void LongRunningProcess();
公共ObservableCollection SomeObjectCollection{get;set;}
私有列表框列表框;
公共ListViewModel(ListBox-ListBox)
{
this.listBox=listBox;
SomeObjectCollection=新的ObservableCollection();
}
公营部门
{
线程线程=新线程(()=>
{
对于(int i=1;i
SomeObjectCollection.Add(i1);
}});
SetApartmentState(ApartmentState.STA);
thread.Start();
}
}
正如您所见,ViewModel现在从UI中了解listBox元素。并且查看MVVM图时,只有视图应该通过绑定引用ViewModel。如何克服此问题?
谢谢。

你需要让你的循环释放对屏幕的更新-某种DoEvents()可以:

添加它并从循环中调用它


使用计时器作为另一个选项,您的代码应该如下所示:

private System.Timers.Timer operationsTimer = new System.Timers.Timer();
private int x;
在您的ctor中:

operationsTimer.Elapsed += new System.Timers.ElapsedEventHandler 
(operationsTimer_Elapsed);
operationsTimer.Enabled = true;
在计时器elpased中:

operationsTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{ 
    operationsTimer.Enabled = false;
    //add item to collection code
    x++;
    if(x<100)
        operationsTimer.Enabled = true;
}
operationsTimer\u已过(对象发送器,System.Timers.ElapsedEventArgs e)
{ 
operationsTimer.Enabled=错误;
//将项目添加到集合代码
x++;

如果(x考虑使用a,这是一种执行异步任务的简单方法,具有报告进度和已完成事件的功能。最重要的是,您不必在调度程序上调用任何东西,因为BackgroundWorker的功能与UI线程同步。

如何克服什么问题?哈哈,很有趣,我实际上发现这是正确的呃,发帖了。但是当我关闭程序时,它会引发一个异常……另一个选择是使用计时器而不是线程循环。如果我能处理这个异常,这听起来像是我想要的解决方案。有没有办法在应用程序关闭时退出所有线程。也许我应该听window.close eventsHow,我会在中使用计时器这种情况下。我想尝试一下,作为另一个选项。谢谢。我会添加定时器选项的答案。
operationsTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{ 
    operationsTimer.Enabled = false;
    //add item to collection code
    x++;
    if(x<100)
        operationsTimer.Enabled = true;
}