使用Newtonsoft.Json
时,在序列化为JSON文件时遇到问题。
在循环中,我在各个线程中执行任务:
List<Task> jockeysTasks = new List<Task>();
for (int i = 1; i < 1100; i++)
{
int j = i;
Task task = Task.Run(async () =>
{
LoadedJockey jockey = new LoadedJockey();
jockey = await Task.Run(() => _scrapServices.ScrapSingleJockeyPL(j));
if (jockey.Name != null)
{
_allJockeys.Add(jockey);
}
UpdateStatusBar = j * 100 / 1100;
if (j % 100 == 0)
{
await Task.Run(() => _dataServices.SaveAllJockeys(_allJockeys)); //saves everything to JSON file
}
});
jockeysTasks.Add(task);
}
await Task.WhenAll(jockeysTasks);
还有if (j % 100 == 0)
,正在努力将集合_allJockeys
保存到文件中(我将做一些计数,使其更可靠,但这不是重点):
public void SaveAllJockeys(List<LoadedJockey> allJockeys)
{
if (allJockeys.Count != 0)
{
if (File.Exists(_jockeysFileName)) File.Delete(_jockeysFileName);
try
{
using (StreamWriter file = File.CreateText(_jockeysFileName))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, allJockeys);
}
}
catch (Exception e)
{
dialog.ShowDialog("Could not save the results, " + e.ToString(), "Error");
}
}
}
在那段时间里,正如我所相信的那样,另一个任务是向集合中添加新的集合项,这给我抛出了一个例外:
集合已修改;枚举操作可能无法执行。
正如我在THE ARTICLE中所阅读的那样,您可以更改迭代类型以避免出现异常。据我所知,我无法修改Newtonsoft.Json
包的工作方式。
在此先感谢您提供任何避免异常的提示,以及如何在不进行意外更改的情况下保存集合。
答案 0 :(得分:0)
您可能应该继承自List并使用ReaderWriterLock(https://docs.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlock?view=netframework-4.8)
即(未经测试的伪C#)
public class MyJockeys: List<LoadedJockey>
{
System.Threading.ReaderWriterLock _rw_lock = new System.Threading.ReaderWriterLock();
public new Add(LoadedJockey j)
{
try
{
_rw_lock.AcquireWriterLock(5000); // or whatever you deem an acceptable timeout
base.Add(j);
}
finally
{
_rw_lock.ReleaseWriterLock();
}
}
public ToJSON()
{
try
{
_rw_lock.AcquireReaderLock(5000); // or whatever you deem an acceptable timeout
string s = ""; // Serialize here using Newtonsoft
return s;
}
finally
{
_rw_lock.ReleaseReaderLock();
}
}
// And override Remove and anything else you need
}
有主意吗?
希望这会有所帮助。
此致
亚当。
答案 1 :(得分:0)
我想在集合上使用ToList()
,这会创建列表的副本,并产生积极的影响。