Here is my MainWindow.
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid Loaded="EmployeesGridLoaded">
<Grid.RowDefinitions>
<RowDefinition Height="6*" />
<RowDefinition />
</Grid.RowDefinitions>
<DataGrid x:Name="gEmployees" HorizontalAlignment="Left" Margin="10,10,0,0"
VerticalAlignment="Top" AlternatingRowBackground="LightBlue" AlternationCount="2" AutoGenerateColumns="False" Grid.Row="0">
<DataGrid.Columns>
<DataGridCheckBoxColumn Header="Select" Binding="{Binding Select}" Width="1*" />
<DataGridTextColumn Header="Last Name" Binding="{Binding LastName}" Width="3*" />
<DataGridTextColumn Header="First Name" Binding="{Binding FirstName}" Width="3*" />
</DataGrid.Columns>
</DataGrid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="5" Grid.Row="1" >
<Button Content="Process" Margin="5" Click="Process_Click" />
<Button Content="Cancel" Margin="5" Click="Cancel_Click" />
</StackPanel>
</Grid>
</Window>
Here is the code.
namespace WpfApplication2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private List<Employee> Employees = null;
public MainWindow()
{
InitializeComponent();
}
private void EmployeesGridLoaded(object sender, RoutedEventArgs e)
{
Employees = new List<Employee>()
{
new Employee() { Select = false, LastName = "Silly", FirstName = "Dude" },
new Employee() { Select = false, LastName = "Mean", FirstName = "Person" },
new Employee() { Select = false, LastName = "New", FirstName = "Friend" },
new Employee() { Select = false, LastName = "My", FirstName = "Buddy" },
};
gEmployees.ItemsSource = Employees;
}
private void Process_Click(object sender, RoutedEventArgs e)
{
Task task = Task.Factory.StartNew(() =>
{
string[] tResults = Employees
.Where(x => x.Select == true)
.AsParallel()
.Select(x => this.DoSomethingWithThisEmployeee(x.LastName, x.FirstName).Result)
.ToArray();
});
Task.WaitAll(task);
System.Windows.MessageBox.Show("Done");
}
private void Cancel_Click(object sender, RoutedEventArgs e)
{
}
private Task<string> DoSomethingWithThisEmployeee(string lastName, string firstName)
{
TaskCompletionSource<string> tcs = new TaskCompletionSource<string>();
Random rand = new Random();
System.Threading.Thread.Sleep(rand.Next(30000, 60000));
tcs.SetResult(lastName + " - " + firstName);
return tcs.Task;
}
}
}
In the code, for each selected employee I have to do some long running operations. Once long running operations are done for all selected employees, the app will do something else. However when these long running operations are running I would like Cancel button to be available so that user can cancel operation. Problem is that Task.WaitAll block the UI and as a result Cancel button is not clickable. Is there any better way of doing this?