The weird thing is that the source for the entities, the import data, hasn't changed for months.
I think all I did was load 2 known entities from the database first and then assign them to the new entities at various places during the import. I even tried, for one of them, setting the ID rather than the entity and still got the crash (it wasn't possible to use the ID for the other - had to assign the entity itself).
So now I need a 5GB stack to run the code just because processing is now in a slightly different order - I think the number of entities is actually the same.
Anyway I am working again with this code in case it helps anyone else out of a spot:
(I had help: see the - aptly named - StackOverflow site - https://stackoverflow.com/questions/54655372/run-process-on-special-thread-and-await-result/54656592)
ThreadHelper.RunOnThreadWithCustomStack(5_000_000, () =>
{
var uow = CreateUnitOfWork();
using (var adapter = new DataAccessAdapter())
{
adapter.StartTransaction(IsolationLevel.Serializable, "X");
uow.Commit(adapter);
adapter.Commit();
}
});
public static class ThreadHelper
{
public static Task<TOut> RunOnThreadWithCustomStack<TIn, TOut>(int stackSize, Func<TIn, TOut> action, TIn arg)
{
var tcs = new TaskCompletionSource<TOut>();
var thread = new Thread(() =>
{
try
{
tcs.SetResult(action(arg));
}
catch (Exception e)
{
tcs.SetException(e);
}
}, stackSize);
thread.Start();
thread.Join();
return tcs.Task;
}
public static Task<TOut> RunOnThreadWithCustomStack<TOut>(int stackSize, Func<TOut> action)
{
var tcs = new TaskCompletionSource<TOut>();
var thread = new Thread(() =>
{
try
{
tcs.SetResult(action());
}
catch (Exception e)
{
tcs.SetException(e);
}
}, stackSize);
thread.Start();
thread.Join();
return tcs.Task;
}
public static void RunOnThreadWithCustomStack(int stackSize, Action action)
{
Exception exception = null;
var thread = new Thread(() =>
{
try
{
action();
}
catch (Exception e)
{
exception = e;
}
}, stackSize);
thread.Start();
thread.Join();
if (exception != null) throw exception;
}