Batch to FireStore: коллекция была изменена;операция перечисления может не выполняться - PullRequest
0 голосов
/ 19 марта 2019

Я видел несколько вопросов по этой теме. Основная причина этой проблемы:

Любая коллекция, которую вы перебираете с помощью foreach, не может быть изменена во время перебора.

В моем случае я не перебираю коллекцию, которую я использую в foreach:

Я хочу написать в FireStore, используя пакет.

код:

WriteBatch batch;
FirestoreDb db = FirestoreDb.Create(projectId);

public async Task publishMessagesPubSub(string message)
{
    try
    {
        PublisherServiceApiClient publisherService = await PublisherServiceApiClient.CreateAsync();
        TopicName topicName = new TopicName(ProjectId, TopicId);
        PublisherClient publisher = await PublisherClient.CreateAsync(topicName);

        DateTime pEnqueuedTimeUtc = new DateTime();
        var records = <...>
        if (records != null && records.Length > 0)
        {
            var orderedRecords = records.ToArray();
            string[] records2 = JSONFormatter.FormatToJson(orderedRecords);
            foreach (string record in records2)
            //Parallel.ForEach(records2, async record =>
            {
                await Task.Run(() => publisher.PublishAsync(record));
                var frameFormatted = JSONtoDict(record);
                await Task.Run(() => StorageMessagesInFireStoreDocumentBatch(frameFormatted, "test"));

                //await publisher.ShutdownAsync(TimeSpan.FromSeconds(15));
            }
            //);
        }
    }
    catch (Exception exc)
    {
        WriteLogEntry("publishMessagesPubSub: Message:" + exc.Message);
    }
}

И метод, которым изменяется коллекция:

private async Task StorageMessagesInFireStoreDocumentBatch(Dictionary<string, object> data, string FireStoreCollection)
{
    try

    {
        if (contadorBatch==0)
            batch = db.StartBatch();
        contadorBatch = contadorBatch + 1;
        CollectionReference FramesCollection = db.Collection(FireStoreCollection);
        DocumentReference   document = FramesCollection.Document();
        batch.Set(document, data);

        if (contadorBatch >= 450)
        {
            contadorBatch = 0;
            var future= batch.CommitAsync().GetAwaiter().GetResult();
            Debug.WriteLine("future.Count(): Message:" + future.Count());
        }
    }
    catch (Exception exc)
    {
        Debug.WriteLine("StorageMessagesInFireStoreDocumentBatch: Message:" + exc.Message);
    }
}

Результат

Иногда данные пишутся без каких-либо проблем, и другие у меня есть это исключение:

StorageMessagesInFireStoreDocumentBatch: Сообщение: коллекция была изменена; операция перечисления может не выполняться.

Как мне сделать это, чтобы добавить элемент в коллекцию FireStore внутри цикла foreach?


EXTRA

Первый подход:

 public async Task publishMessagesPubSub(string message)
        {
            try
            {
                PublisherServiceApiClient publisherService = await PublisherServiceApiClient.CreateAsync();
                TopicName topicName = new TopicName(ProjectId, TopicId);
                PublisherClient publisher = await PublisherClient.CreateAsync(topicName);                
                //Dictionary<string, object> frameFormatted;
                WriteBatch batch = db.StartBatch();
                DateTime pEnqueuedTimeUtc = new DateTime();
                var records = <...>;
                if (records != null && records.Length > 0)
                {
                    var orderedRecords = records.ToArray();
                    string[] records2 = JSONFormatter.FormatToJson(orderedRecords);
                    //foreach (string record in records2)
                    Parallel.ForEach(records2, async record =>
                    {
                        await Task.Run(() => publisher.PublishAsync(record));
                        await Task.Run(() => StorageMessagesInFireStoreDocumentBatch(JSONtoDict(record), document, batch));                       
                    }
                    );
                }
            }
            catch (Exception exc)
            {
                WriteLogEntry("publishMessagesPubSub: Message:" + exc.Message);
            }
        }


private async Task StorageMessagesInFireStoreDocumentBatch(Dictionary<string, object> data, DocumentReference document, WriteBatch batch)
{
    try
    {
        batch.Set(document, data);
        var future= await  batch.CommitAsync();
        Debug.WriteLine("future.Count(): Message:" + future.Count());

    }
    catch (Exception exc)
    {
        Debug.WriteLine("StorageMessagesInFireStoreDocumentBatch: Message:" + exc.Message);
        //WriteLogEntry("StorageMessagesInFireStoreDocumentBatch: Message:" + exc.Message);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...