2016-12-30 4 views
0

Я подготовил следующий код в приложении WPF. Этот код просто запрашивает список контактов CRM и помещает его в коллекцию, которая затем отображается в элементе управления ListBox.Динамика CRM - аннулирование запроса и получение частичных результатов

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> 

Код:

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; 
     }; 


    } 
} 

Процесс загрузки контактов может быть прервана пользователем. Вся загрузка контактов выполняется с помощью TPL с маркером отмены. 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; 
     }); 
    } 

После возможного прерывания операции я получаю пустой список. Сейчас все в порядке, но мне просто интересно, есть ли возможность отменить операцию и получить неполный список контактов, а не просто пустой или полный список.

+0

я сомневаюсь, предлагает с помощью 'метод AsParallel' никакой пользы здесь вообще. Большая часть времени обработки тратится на выполнение запроса 'ContactSet'. После получения результирующего набора преобразование в «Список » является тривиальным. Я предполагаю, что использование параллельной обработки здесь займет больше времени, чем в одном потоке. –

+0

Спасибо Хенк. Возможно, вы правы. Я снова рассмотрю код. –

ответ

0

Вы можете распечатать результаты запроса с небольшим размером страницы (1-3, я бы сказал), вы будете забивать систему, но добиваетесь того, чего хотите.

Что я имею в виду под ударами: если у вас есть 100 записей, вы можете запросить их все нормально (1 запрос -> 100 результатов: отмена оставляет вас пустыми). Если размер страницы равен 2, вы должны запросить CRM 50 раз (50x2 = 100 результатов. Отмена оставляет вас с результатами любого количества запросов, которые вы выполнили во время работы).

Если вы реализуете это, смотреть сети, вы могли бы в конечном итоге DoS-ING себя ...

+0

Это действительно жестокое обращение с конечными точками. Спасибо, Алекс. Скорее, я закрываю эту академическую проблему и возвращаюсь к традиционному запросу Dynamics ... –

Смежные вопросы