I am developing a WPF app, to generate folders dynamically
Right now I have an issue with what happens if the user puts 10000 folders? I am trying to run my for loop in another thread
By the way, how can I limit the user to create x number of folders? Code Behind:
public MainWindowVM() {
SaveCommand = new Command(SaveAction);
FoldersCollection = new ObservableCollection<FolderData>();
CreateCommand = new Command(CreateAction);
CreateFoldersCommand = new Command(CreateFolderAction);
}
private void SaveAction() {
}
private void CreateFolderAction() {
var dirrName = "Assets";
var workingDirectory = Environment.CurrentDirectory;
// This will get the current PROJECT directory
var projectDirectories = Directory.GetParent(workingDirectory).Parent.Parent.GetDirectories(dirrName)
.ToList();
var path = Path.GetFullPath(projectDirectories.First().FullName);
foreach (var item in FoldersCollection) {
Directory.CreateDirectory($"{path}\\{item.FolderName}");
}
}
private void CreateAction() {
for (int i = 0; i < Value; i ) {
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate {
FoldersCollection.Add(new FolderData() { FolderID = i, FolderName = string.Empty, Extenion = new List<string>() });
}));
XAML:
<WrapPanel>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="600" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="110" />
<ColumnDefinition Width="400" />
</Grid.ColumnDefinitions>
<Label Content="Number of folders: " />
<TextBox
Grid.Column="1"
VerticalAlignment="Center"
PreviewTextInput="FolderNames_count"
Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" />
<Button
Grid.Column="1"
HorizontalAlignment="Right"
VerticalAlignment="Center"
BorderBrush="Transparent"
Command="{Binding CreateCommand}"
Content="Create"
Focusable="False" />
<ScrollViewer
Grid.Row="1"
Grid.ColumnSpan="2"
Margin="10"
BorderBrush="Transparent"
Focusable="False"
HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding FoldersCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock
Margin="0,10,0,0"
VerticalAlignment="Center"
FontStyle="Oblique"
Text="{Binding FolderID}" />
<syncfusion:SfTextBoxExt
Width="300"
Margin="10,10,0,0"
VerticalAlignment="Center"
Text="{Binding FolderName, UpdateSourceTrigger=PropertyChanged}"
Watermark="Folder Name" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<Button
Grid.Row="2"
VerticalAlignment="Center"
Command="{Binding CreateFoldersCommand}"
Content="Create structure"
Style="{StaticResource MenuItem}" />
<Button
Grid.Row="2"
Grid.Column="1"
Margin="5,0,0,0"
VerticalAlignment="Center"
Command="{Binding SaveCommand}"
Content="Save structure"
Style="{StaticResource MenuItem}" />
</Grid>
</WrapPanel>
The app works fine, but when I exit, I get this error
btw I am doing this to allow numbers in my textbox
private void FolderNames_count(object sender, TextCompositionEventArgs e) {
if (!char.IsDigit(e.Text, e.Text.Length - 1))
e.Handled = true;
}
CodePudding user response:
If you commands run on separate thread, then it looks like the bg thread still running during GUI thread is finished.
My recommendation is to put the handling of this case to the Window.Closing
handler, i.e. do notify thread to break the loop, e.g. set cancellation token.
The brutal option would be to call Enviroment.Exit(0)
method in the Window.Closing
or Window.Closed
handler, to terminate all threads. See Environment.Exit(Int32) Method
CodePudding user response:
It's the loop should be executed on a background thread:
private void CreateAction()
{
Task.Run(() =>
{
for (int i = 0; i < Value; i )
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
FoldersCollection.Add(new FolderData() { FolderID = i })));
}
});
}