diff --git a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs index 8af872987..35abf12f4 100644 --- a/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs +++ b/dotnet/src/dotnetframework/GxClasses/Core/GXApplication.cs @@ -3410,7 +3410,7 @@ public IGxSession GetSession() } internal bool IsStandalone => this._session is GxSession || this._isSumbited || this.HttpContext == null; - + internal bool IsSubmited => this._isSumbited; internal void SetSession(IGxSession value) { if (value != null) diff --git a/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs b/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs index 853f2b4a0..3ab98ae8a 100644 --- a/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs +++ b/dotnet/src/dotnetframework/GxClasses/Model/gxproc.cs @@ -42,7 +42,7 @@ public abstract class GXProcedure: GXBaseObject protected string Gx_out = ""; protected string Gx_docfmt = ""; protected string Gx_docname = ""; - + const int SLEEP_BETWEEN_CHECKS_ON_THREADS = 500; public const int IN_NEW_UTL = -2; private bool disconnectUserAtCleanup; #if !NETCORE @@ -90,6 +90,9 @@ protected void exitApplication() } private void exitApplication(bool flushBatchCursor) { + if (IsMain && !(context as GxContext).IsSubmited) + WaitForThreadPoolEnd(); + if (flushBatchCursor) { foreach (IGxDataStore ds in context.DataStores) @@ -114,6 +117,19 @@ private void exitApplication(bool flushBatchCursor) #endif } + void WaitForThreadPoolEnd() + { + bool working = true; + ThreadPool.GetMaxThreads(out int maxWorkerThreads, out _); + while (working) + { + ThreadPool.GetAvailableThreads(out int workerThreads, out _); + if (workerThreads == maxWorkerThreads) + working = false; + else + Thread.Sleep(SLEEP_BETWEEN_CHECKS_ON_THREADS); + } + } protected virtual bool BatchCursorHolder() { return false; } protected virtual void printHeaders(){} protected virtual void printFooters(){}