【问题标题】:EWS error: Exceeded maximum count of 1000 items that can be deleted in a single requestEWS 错误:超过了可以在单个请求中删除的 1000 个项目的最大计数
【发布时间】:2018-04-13 20:20:34
【问题描述】:

我正在使用 EWS Exchange Sync,并且在我的一种方法中,它表示我超过了可以在单个请求中删除的 1000 个项目的最大计数。是否可以通过不删除日历中的所有内容来解决这个问题,我们只从今天起删除,而不是及时删除?

导致错误的方法在这里:

        public void DeleteAllSafeAppointments(SCDriftConnection conn, ExchangeService service, SAFEAgent agent) {
        if(conn == null)
            throw new ArgumentNullException("conn");
        if(service == null)
            throw new ArgumentNullException("service");
        if(agent == null)
            throw new ArgumentNullException("agent");

        try {
            var calendar = GetAgentCalendar(service, agent);

            service.DeleteItems(GetAllSafeAppointments(calendar).Select(a => a.Id), DeleteMode.HardDelete, SendCancellationsMode.SendToNone, null);

            var scheduledActivitiesOnAgent = ScheduledActivity.GetScheduleToExchange(new QueryParameters<ScheduledActivity>(s => s.Initials == agent.Initials && s.ExchangeId != null));

            foreach(var schedAct in scheduledActivitiesOnAgent) {
                schedAct.ExchangeId = null;

                schedAct.Save(conn);
            }

            ResetAgentSyncState(calendar, agent);
        } catch(Exception ex) {
            throw new Exception("An error occured while clearing exchange calendar for " + agent.Initials, ex);
        }

        agent.ExchangeSyncronizationSettings.LastSync = DateTime.Now;
        agent.ExchangeSyncronizationSettings.Save(conn);
    }

完整的错误信息在这里:

> Safe-Exchange 同步发生错误,版本=1.0.0.0,文化=中性,PublicKeyToken=null

单个请求中可删除的项目数量已超过 1000 个。 已验证 Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ProcessWebException(WebException webException) 已验证 Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest 请求) 已验证 Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(IEwsHttpWebRequest& 请求) ved Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest1.Execute() ved Microsoft.Exchange.WebServices.Data.ExchangeService.InternalDeleteItems(IEnumerable1 itemIds,DeleteMode deleteMode,Nullable1 sendCancellationsMode, Nullable1 受影响的TaskOccurrences,ServiceErrorHandling errorHandling,布尔型suppressReadReceipts) 已验证 Microsoft.Exchange.WebServices.Data.ExchangeService.DeleteItems(IEnumerable1 itemIds, DeleteMode deleteMode, Nullable1 sendCancellationsMode,Nullable`1 受影响的TaskOccurrences) ved SafeToExchangeSync.SafeScheduleSyncronizer.DeleteAllSafeAppointments(SCDriftConnection conn,ExchangeService 服务,SAFEAgent 代理)

【问题讨论】:

  • 只发出多个请求有什么问题?
  • 没什么,但在这个具体的例子中,我不想及时删除,而是想从今天开始删除。
  • 为什么不提出这个问题而不是这个错误?简而言之,不,不能通过从今天开始删除所有内容来解决:考虑从今天开始有超过 1000 个项目的情况。
  • 嗯,我知道从今天起不会超过 1000 个项目,请说明应该怎么做?除了发出多个请求并因此重写很多。
  • 为什么不通过 Deleteitems 方法循环 1000 个批次?似乎不需要太多的重写。

标签: c# synchronization exchangewebservices


【解决方案1】:

您可以批量处理请求。我为此编写了一个通用批处理方法:

private IEnumerable<IEnumerable<T>> Batch<T>(IEnumerable<T> input, int batchSize)
{
    List<T> items = new List<T>();
    foreach (var item in input)
    {
        items.Add(item);
        if (items.Count == batchSize)
        {
            yield return items;
            items = new List<T>();
        }
    }
    if (items.Count > 0)
    {
        yield return items;
    }
}

您现在可以使用它来将您的物品分成多个批次:

var batches = Batch(GetAllSafeAppointments(calendar).Select(a => a.Id), 1000);
foreach (var batch in batches)
{
    service.DeleteItems(batch, DeleteMode.HardDelete, SendCancellationsMode.SendToNone, null);
}

现在一次最多删除 1000 个。

【讨论】:

  • 谢谢,我对 C# 很陌生,并且使用 EWS,所以我没有想到这一点。通用批处理方法我需要更改任何变量,还是我可以以这种确切的方式实现您提出的解决方案?
  • 您可以按原样使用 Batch 方法 - 它采用通用 T,因此它会自动根据传入的内容推断类型。
  • 我不熟悉 Exchange API,但我将假设以下两种情况之一:1) 由于请求过多(您要删除多少项目?)或 2,它会受到限制) 批次中的某些 ID 已被删除(是否有重复)? - 您可能需要发布一个单独的问题,因为我无法为该特定消息提供帮助。
  • 除了这样做之外,您还有其他解决方法吗?也许使用日期仅删除今天/以后的项目?
  • @kwesi 如果GetAllSafeAppointments 返回的项目包含日期,您可以执行.Where(a =&gt; a.datefield &gt;= DateTime.Now.Date).Select(a =&gt; a.Id)) 之类的操作
【解决方案2】:
private IEnumerable<Appointment> GetAllSafeAppointments(Folder calendar) {
            ItemView view = new ItemView(512);

            view.PropertySet = new PropertySet(BasePropertySet.IdOnly);

            SearchFilter filter = new SearchFilter.SearchFilterCollection(LogicalOperator.And,
                                                                          new SearchFilter.IsEqualTo(SafeAppointmentFlag, true));

            while(true) {
                var results = SendExchangeRequest(() => calendar.FindItems(filter, view));

                foreach(var r in results.OfType<Appointment>())
                    yield return r;

                if(!results.MoreAvailable)
                    break;

                view.Offset = results.NextPageOffset.Value;
            }
        }

【讨论】:

    猜你喜欢
    • 2016-12-14
    • 1970-01-01
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-03
    • 2020-07-01
    相关资源
    最近更新 更多