如何减少 Dynamics 365 中多个请求的执行时间
How to decrease the execution time of multiple requests in Dynamics 365
我有大麻烦了。我在代码中的多个请求的执行时间比 azure 应用程序超时时间长。我需要更新很多记录,最后 return 将一些数据更新到 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;
}
}
尝试重构您的代码以使用:
- 并行编程(如 C# 中的
Parallel.ForEach
、Parallel.For
for example 或
- Pure multi-threading 因此让多个工作线程同时协作处理多个更新。在这方面,您可以在并发队列中共享
EntityCollection
(C# for example 中的 ConcurrentQueue<T>
)。
如果在解决方案中配置线程数和多个更新的批大小,可以更轻松地测试 Azure 超时。
- 线程的尽可能多的 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);
}
}
}
}
我有大麻烦了。我在代码中的多个请求的执行时间比 azure 应用程序超时时间长。我需要更新很多记录,最后 return 将一些数据更新到 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;
}
}
尝试重构您的代码以使用:
- 并行编程(如 C# 中的
Parallel.ForEach
、Parallel.For
for example 或 - Pure multi-threading 因此让多个工作线程同时协作处理多个更新。在这方面,您可以在并发队列中共享
EntityCollection
(C# for example 中的ConcurrentQueue<T>
)。
如果在解决方案中配置线程数和多个更新的批大小,可以更轻松地测试 Azure 超时。 - 线程的尽可能多的 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);
}
}
}
}