Я видел несколько вопросов по этой теме. Основная причина этой проблемы:
Любая коллекция, которую вы перебираете с помощью 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);
}
}