Ich habe folgenden Code in WPF App vorbereitet. Dieser Code fragt einfach die CRM-Kontaktliste ab und speichert sie in der Sammlung, die dann im ListBox-Steuerelement angezeigt wird.Dynamics CRM - Abfrage Stornierung und erhalten Teilergebnisse
XAML:
<Window x:Class="WPFDynamics365.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDynamics365"
xmlns:fa="http://schemas.fontawesome.io/icons/"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<Window.Resources>
<Storyboard x:Key="WaitStoryboard">
<DoubleAnimation
Storyboard.TargetName="Wait"
Storyboard.TargetProperty="(TextBlock.RenderTransform).(RotateTransform.Angle)"
From="0"
To="360"
Duration="0:0:2"
RepeatBehavior="Forever" />
</Storyboard>
</Window.Resources>
<Grid Name="mainGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"></RowDefinition>
<RowDefinition Height="6*"></RowDefinition>
<RowDefinition Height="2*"></RowDefinition>
</Grid.RowDefinitions>
<!-- fa to jest TextBlock -->
<fa:FontAwesome
Panel.ZIndex="999" Icon="Spinner" Name="Wait"
Grid.Column="0" Grid.Row="1"
HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="50"
RenderTransformOrigin="0.5, 0.5" Margin="20" Width="100">
<TextBlock.RenderTransform>
<RotateTransform Angle="0" />
</TextBlock.RenderTransform>
</fa:FontAwesome>
<Label Margin="0,20,0,0" FontSize="20" HorizontalAlignment="Center" Width="100" Grid.Row="0" Name="count"></Label>
<ListBox
DisplayMemberPath="FullName" SelectedValuePath="Id" Name="contactList"
Grid.Column="0" Grid.Row="1" Panel.ZIndex="0"
Width="300" Height="300" HorizontalAlignment="Center">
</ListBox>
<Button Grid.Column="0" Grid.Row="2"
Width="200" Height="50" Margin="0,10,0,0"
Name="cancel" Content="Stop downoloading Contacts">
</Button>
</Grid>
Code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += async (sender, args) =>
{
CancellationTokenSource tokenSource = new CancellationTokenSource();
cancel.AddHandler(Button.ClickEvent, new RoutedEventHandler((s, a) =>
{
tokenSource.Cancel();
}));
var context = App.CRM.Context;
CrmFactor factor = CrmFactor.Create();
((Storyboard)FindResource("WaitStoryboard")).Begin();
EntitiesExplorer exp = new EntitiesExplorer(factor);
var contacts = await exp.GetContacts(tokenSource.Token);
count.Content = contacts?.Count.ToString();
contactList.ItemsSource = contacts;
((Storyboard)FindResource("WaitStoryboard")).Stop();
Wait.Visibility = Visibility.Collapsed;
};
}
}
Der Prozess des Herunterladens Kontakte können vom Benutzer unterbrochen werden. Der gesamte Kontakt-Download erfolgt über TPL mit Abbruch-Token. Getter:
public async Task<List<Contact>> GetContacts(CancellationToken ct)
{
List<Contact> list = new List<Contact>();
return await System.Threading.Tasks.Task.Run(() =>
{
try
{
list = _crmFactor.Context.ContactSet.AsParallel().WithCancellation(ct).ToList();
}
catch { }
return list;
});
}
Nach einer möglichen Unterbrechung des Betriebs erhalte ich eine leere Liste. Das ist jetzt in Ordnung, aber ich bin nur neugierig, ob es eine Möglichkeit gibt, den Vorgang abzubrechen und eine unvollständige Liste von Kontakten zu erhalten, nicht nur eine leere oder vollständige Liste.
ich zweifle, ob die 'AsParallel' Methode hier überhaupt keinen Nutzen bietet. Die meiste Verarbeitungszeit wird für die Ausführung der Abfrage 'ContactSet' benötigt. Sobald die Ergebnismenge empfangen wurde, ist die Umwandlung in eine "Liste" nur trivial. Meine Vermutung ist, dass die parallele Verarbeitung hier mehr Zeit in Anspruch nimmt als dasselbe in einem einzigen Thread. –
Danke Henk. Wahrscheinlich hast du recht. Ich werde den Code erneut prüfen. –