如何减少Dynamics 365中多个请求的执行时间



我遇到大麻烦了。我在代码中的多个请求的执行时间比azure应用程序超时时间长。我需要更新很多记录,最后将一些数据返回到azure中的网站。我正在发送一批200条更新200条记录的请求。我需要一种更快的方式来批量更新记录。

我的代码:

public static Boolean BulkUpdateNoSorteado(CrmServiceClient service, EntityCollection entities)
{
// Create an ExecuteMultipleRequest object.
var multipleRequest = new ExecuteMultipleRequest()
{
// Assign settings that define execution behavior: continue on error, return responses. 
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = false,
ReturnResponses = true
},
// Create an empty organization request collection.
Requests = new OrganizationRequestCollection()
};
try
{
var countRequest = Int32.Parse(ConfigurationManager.AppSettings["requestCount"]);

// Add a UpdateRequest for each entity to the request collection.
foreach (var entity in entities.Entities)
{
SetStateRequest request = new SetStateRequest
{
EntityMoniker = new EntityReference(entity.LogicalName, entity.Id),
State = new OptionSetValue(1),
Status = new OptionSetValue((int)Domain.Enum.EnumStatusTicket.Nao_sorteado)
};
multipleRequest.Requests.Add(request);
if (multipleRequest.Requests.Count == countRequest || entity == entities.Entities.Last())
{
if (service.OrganizationServiceProxy == null)
{
service = FactoryGetService.AccessTokenGeneratorAsync();
}
ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);
multipleRequest = new ExecuteMultipleRequest()
{
// Assign settings that define execution behavior: continue on error, return responses. 
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = false,
ReturnResponses = true
},
// Create an empty organization request collection.
Requests = new OrganizationRequestCollection()
};
}
}
return true;
} 
catch (Exception)
{
throw;
}
}

尝试重构代码以使用:

  1. 并行编程(例如C#中的Parallel.ForEachParallel.For
  2. 纯多线程,因此允许多个工作线程同时对多个更新进行协作。在这方面,您可以在并发队列中共享EntityCollection(例如C#中的ConcurrentQueue<T>(
    如果您在解决方案中配置多个更新的线程数和批量大小,您可以更容易地测试Azure超时
  3. 线程的尽可能多的CRM组织URL

下面是2中的代码。可能看起来像:

using System;
using System.Threading;
using System.Data;
using System.Linq;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
public class EntitiesPage : List<Entity> { }

public class MultiThreadedDynamicsCrmUpdate
{        
//EntityCollection ec = ...;
//CrmServiceClient service = FactoryGetService.AccessTokenGeneratorAsync();
//int statusOptionSetValue = (int)Domain.Enum.EnumStatusTicket.Nao_sorteado;

int updatesPageSize = 200;
int threadsNumber = 10;
ConcurrentQueue<EntitiesPage> cq = new ConcurrentQueue<EntitiesPage>();

public static void Main(string[] args)
{
UpdateAll();
}
public static void UpdateAll()
{
PaginateEntities(ec);
List<Thread> threads = new List<Thread>();
for (int i = 0; i < threadsNumber; i++)
{
threads.Add(new Thread(UpdateACrmEntitiesPageByThread));
}
foreach (Thread thread in threads)
{
thread.Start();
}
foreach (Thread thread in threads)
{
thread.Join();
}
}

public static void PaginateEntities(EntityCollection ec)
{
EntitiesPage page = new EntitiesPage();

foreach (Entity e in ec.Entities)
{
page.Add(e);
if (page.Count == updatesPageSize)
{
cq.Enqueue(page);
page = new EntitiesPage();
}
}
cq.Enqueue(page);
}
public static void UpdateACrmEntitiesPageByThread()
{
EntitiesPage page = new EntitiesPage();
while (!cq.IsEmpty)
{ 
if (cq.TryDequeue(out page))
{
var multipleRequest = new ExecuteMultipleRequest()
{
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = false,
ReturnResponses = true
},
Requests = new OrganizationRequestCollection()
};
foreach (Entity e in page)
{
SetStateRequest request = new SetStateRequest
{
EntityMoniker = new EntityReference(e.LogicalName, e.Id),
State = new OptionSetValue(1),
Status = new OptionSetValue(...)
};
multipleRequest.Requests.Add(request);
}
ExecuteMultipleResponse multipleResponse = (ExecuteMultipleResponse)service.Execute(multipleRequest);
}
}
}
}

最新更新