In the case when my program performs resource-intensive tasks, I start them in a separate thread and all the buzz. BUT there was such a case when I assign a fairly large collection to the control, and also a composite of objects, and at that moment, on the one hand, I cannot start this work in a separate thread, on the other hand, the UI hangs tight seconds for 5.

ListView1.ItemsSource = objectsListForBindingAll; 

How to be in such cases? This command alone slows down everything for seconds, and I would like to show progress bar undefined instead of brakes?

  • I advise you to do as in this article. - Vlad
  • By itself, such a command can not slow down the UI for a long time. Roll out the reproducing example to make it clear what you are doing wrong. Maybe your sequence is dynamically generated with a database request? Or maybe you want to show the user a million items in a non-virtual ListView? You never know what may be errors. - VladD
  • Vlad, your link to cool. does not fit me. VladDe, I cannot show an example because it is long and there is no sense in it. I have a List <T> objectsListForBindingAll which is collected in a separate thread before I assign it to the View list and I can assure you that the window hangs up during this assignment. At that time, no other operations occur. The elements are not a million, but about a thousand, but apparently this is enough for the brakes, because the elements are composite and not stupid lines. - beatsspam
  • Why it is impossible to first collect your collection in a separate stream, and then later display it? - Bulson
  • 2
    @beatsspam: Well, if you don’t give a reproducing example, it will be difficult to help us. In my code, for example, the list of 1000 elements does not represent any problem at all, so the problem is not quantity. So it is in your best interest to make the problem reproduce with us. - VladD

3 answers 3

Add a normal datagrid to the form that can virtualize. Everything was done in a couple of clicks was. Create a data source for an Objects.cs object and drag a sheet onto the form. Everything is created automatically.

  <Grid DataContext="{StaticResource rootObjectLekarstvoViewSource}"> <DataGrid x:Name="listDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding Source={StaticResource rootObjectLekarstvolistViewSource}}" Margin="0,109,117,10" RowDetailsVisibilityMode="VisibleWhenSelected"> <DataGrid.Columns> <DataGridTextColumn x:Name="byeLinkColumn" Binding="{Binding byeLink}" Header="bye Link" Width="SizeToHeader"/> <DataGridTextColumn x:Name="drug_codeColumn" Binding="{Binding drug_code}" Header="drug code" Width="SizeToHeader"/> <DataGridCheckBoxColumn x:Name="isOnColumn" Binding="{Binding isOn}" Header="is On" Width="SizeToHeader"/> <DataGridCheckBoxColumn x:Name="online_storeColumn" Binding="{Binding online_store}" Header="online store" Width="SizeToHeader"/> <DataGridTextColumn x:Name="priceColumn" Binding="{Binding price}" Header="price" Width="SizeToHeader"/> <DataGridCheckBoxColumn x:Name="reserveLinkColumn" Binding="{Binding reserveLink}" Header="reserve Link" Width="SizeToHeader"/> <DataGridTextColumn x:Name="updatedColumn" Binding="{Binding updated}" Header="updated" Width="SizeToHeader"/> </DataGrid.Columns> </DataGrid> <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="155,255,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/> </Grid> 
  private async void button_Click(object sender, RoutedEventArgs e) { var json = await new HttpClient().GetStringAsync("http://contrib.gpor.ru/pharmacyImport/feed/pharmacyFeed_60.json"); var data = JsonConvert.DeserializeObject<RootObjectLekarstvo>(json); listDataGrid.ItemsSource = data.list; } 

At the output, 10k of data was downloaded from the Internet and added to the table asynchronously, the interface did not hang.

  • An interesting option is to replace ListView with a DataGrid, and it works. I doubt that asynchronously, just the DataGrid works very quickly and the UI does not have time to stop for visible time. Vprintsype while then so do. Thanks - beatsspam
  • one
    It does not work faster, it virtualizes and loads if necessary. By the way, the operational memory consumption is significantly less. At 10k values ​​you ate about a gigabyte and still did not display the data. - Morgomirius

If the collection is large and it slows down the UI when trying to display it in its entirety, then this partitions up the collection into parts and the sequential display of parts, that is, the so-called pagination.

    And run this add asynchronously does not work? For example, here is await Dispatcher.RunAsync (CoreDispatcherPriority.Normal, () => {Adding a list here});

    • I would like to check your method, but unfortunately “Error CS1061 'Dispatcher” does not contain a definition for “RunAsync” and could not find the extension method “RunAsync”. Probably this is not for desktop programs but for the store. - beatsspam
    • await Task.Factory either? Or with the dispatcher try InvokeAsync (). Read about asynchronous programming, you may have missed some point. Alternatively, create an asynchronous method. private Task SetItemsSource () {insert your assignment here}. In code, call it through await. And yes, if this operation is not performed in the user thread (will not be caused by a user action), then there will be an error. Calling a UI from another thread only through the dispatcher is implemented. This is so, for the future, can save you a couple of hours of time :) - Morgomirius
    • checked all that you listed. also not (When doing as you said from another thread, nothing slows down but an error, but from UI it works but it slows down. If you put it in another thread into the Invoke dispatcher - beatsspam
    • If you put it in another thread in the Invoke Dispatch, then again the control will return the command to the UI stream and the UI will hang accordingly (. In the comment to the 1st post, I attached a link to the program’s sources if you have time to check and check with yourself - beatsspam