Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.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# 并行/异步负载沉重的ui wpf_C#_Wpf_Asynchronous_Mvvm_Task Parallel Library - Fatal编程技术网

C# 并行/异步负载沉重的ui wpf

C# 并行/异步负载沉重的ui wpf,c#,wpf,asynchronous,mvvm,task-parallel-library,C#,Wpf,Asynchronous,Mvvm,Task Parallel Library,我在加载我的应用程序时遇到一些问题,这需要花费太多时间。所以我想使用.NET4.5优化代码。对于WCF调用、I/O操作和一些计算,我已经用异步/等待模式替换了代码。我甚至使用GZip压缩来减少加载时间。它工作得很好,我节省了几秒钟 经过几次测试,我意识到主要加载时间是由于UI初始化(>20s) 我的应用程序基于MVVM Light框架。一个main窗口绑定在MainViewModel上。MainViewModel有一个List-DataViewModelList属性。每个DataViewMode

我在加载我的应用程序时遇到一些问题,这需要花费太多时间。所以我想使用.NET4.5优化代码。对于WCF调用、I/O操作和一些计算,我已经用异步/等待模式替换了代码。我甚至使用GZip压缩来减少加载时间。它工作得很好,我节省了几秒钟

经过几次测试,我意识到主要加载时间是由于UI初始化(>20s)

我的应用程序基于MVVM Light框架。一个
main窗口
绑定在
MainViewModel
上。
MainViewModel
有一个
List-DataViewModelList
属性。每个
DataViewModel
都有一个
List ViewModelBaseList
属性。那些
ViewModelBase
可以
ServiceUnitViewModel
类型化绑定到
ServiceUnitView
SearchViewModel
类型化绑定到
SearchView

main窗口由
TabControl
ItemsSource={Binding dataviewmodelsist}
组成。因此它的
TabItem
datacontext是一个
DataViewModel
。每个
TabItem
都是一个
TabControl
,带有
ItemsSource={Binding ViewModelBaseList}
。每个
TabItem
都是一个
UserControl
,其数据上下文是
ServiceUnitViewModel
SearchViewModel
。。。在选择=>
DataViewModel x+ViewModelBase y之后,一次显示一个视图(
ServiceUnitView
SearchView
…)

//MainViewModel.cs
public class MainViewModel : ViewModelBase
{
    private List<DataViewModel> _dataViewModelList;
    public List<DataViewModel> DataViewModelList
    {
        get { return _dataViewModelList; }
        set
        {
            if (_dataViewModelList == value)
                return;

            _dataViewModelList = value;
            RaisePropertyChanged("DataViewModelList");
        }
    }

    public MainViewModel()
    {
        DataViewModelList = new List<DataViewModel>();
    }
}

//DataViewModel.cs
public class DataViewModel : ViewModelBase
{
    public MainViewModel MainViewModel { get; set; }

    private ObservableCollection<ViewModelBase> _viewModelBaseList;
    public ObservableCollection<ViewModelBase> ViewModelBaseList
    {
        get { return _viewModelBaseList; }
        set
        {
            if (_viewModelBaseList == value)
                return;

            _viewModelBaseList = value;
            RaisePropertyChanged("ViewModelBaseList");
        }
    }

    public DataViewModel(MainViewModel mainViewModel)
    {
        MainViewModel = mainViewModel;
        ViewModelBaseList = new ObservableCollection<ViewModelBase>();
    }
}

//ServiceUnitViewModel.cs
public class ServiceUnitViewModel : ViewModelBase
{
    public DataViewModel DataViewModel { get; set; }
    public ServiceUnitView View { get; set; }

    public ServiceUnitViewModel(DataViewModel dataViewModel)
    {
        DataViewModel = dataViewModel;
        View = new ServiceUnitView(this);
    }
}

//SearchViewModel.cs
public class SearchViewModel : ViewModelBase
{
    public DataViewModel DataViewModel { get; set; }
    public SearchView View { get; set; }

    public SearchViewModel(DataViewModel dataViewModel)
    {
        DataViewModel = dataViewModel;
        View = new SearchView(this);
    }
}

//MainWindow.cs
<TabControlEx x:Name="TabControl" ItemsSource="{Binding DataViewModelList}" SelectedItem="{Binding SelectedDataViewModel}">
<TabControlEx.Resources>
    <Style TargetType="TabItem" BasedOn="{StaticResource TabItemStyle}">
        <Setter Property="IsSelected" Value="{Binding DataViewModelIsSelected}"/>
    </Style>
</TabControlEx.Resources>
<TabControlEx.ContentTemplate>
    <DataTemplate>
        <TabControlEx ItemsSource="{Binding ViewModelBaseList}" SelectedItem="{Binding SelectedViewModelBase}">
            <TabControlEx.ContentTemplate>
                <DataTemplate>
                    <UserControl Content="{Binding View}"/>
                </DataTemplate>
            </TabControlEx.ContentTemplate>
            <TabControlEx.Resources>
                <Style TargetType="TabItem" BasedOn="{StaticResource TabItemStyle}">
                    <Setter Property="IsSelected" Value="{Binding ViewModelBaseIsSelected}"/>
                </Style>
            </TabControlEx.Resources>
        </TabControlEx>
    </DataTemplate>
</TabControlEx.ContentTemplate>
与Parallel.ForEach类似的问题

有没有一种方法可以在不冻结ui的情况下加载大量嵌套的UserControl。使用并行负载减少时间?我尝试了Dispatcher.Invoke stuff来警告UI线程更新UI,但我的主要问题是创建视图,这样就不会更改任何内容(相同的加载时间)。ui加载仍然是按顺序进行的,不是吗? 有很多教程,但每次都是太简单的示例(Console.Writeline、I/O上的异步/并行、WCF、数据库…,没有ui更新),或者ui更新是同步进行的(相当于完成的backgroundworker)

我从(非常好的家伙)那里读了很多出版物
和其他的帖子,因为8天,我不能自己做这件事,我需要你的帮助。如果您需要澄清,请告诉我。

我们正在通过在同一网格中使用两个控件来解决类似问题-一个是忙指示器(圆形),另一个是实际控件。后台任务完成后,我们只需切换控件的可见性-隐藏忙碌指示器并显示真正的控件。您知道瓶颈在哪里吗?在UI构建期间,您是否有任何CPU密集型/IO操作?20秒对于构建UI来说是相当多的时间。@smartobelix的目的是加速治疗。我首先做的是显示:
加载服务1-加载床视图-加载搜索视图
加载服务2-加载床视图-加载搜索视图确定,然后您应该在并行任务中创建视图模型,但在最后,使用Dispatcher.Invoke或更好的BeginInvoke将它们分配给属性。@sondergard客户机:奔腾DualCore 3.20GHz 4go。前20秒(初始化)大约10%到20%,然后渲染大约40%,我猜是最后5秒
foreach(Service service in User.Services)
{
    await Task.Run(() =>
    {
        //crash after a while when trying to update some UI Control (refresh method)(DependencySource must be on same Thread that DependencyObject)
        DataViewModel dataViewModel = new DataViewModel(MainViewModel);
        MainViewModel.DataViewModelList.Add(dataViewModel);

        await Task.Run(() =>
        {
            foreach(string view in service.views)
            {
                ViewModelBase vmb;
                if (view == "ServiceUnitView")
                    //crash because i can't do View = new ServiceUnitView(this) in ServiceUnitViewModel because it's not the UI thread
                    vmb = new ServiceUnitViewModel(dataViewModel);
                else if (view == "SearchView")
                    vmb = new SearchViewModel(dataViewModel);
                else
                    continue;

                dataViewModel.ViewModelBaseList.Add(vmb); 
            }
        }
    }
}