Disposable Objects When Closing a WinForm Application

I have a Windows Forms application that connects to a database. All complex SQL queries are executed in the background thread, so they do not block the main thread. Some of these queries require a database transaction. All Db objects are initialized using the keyword to ensure proper disposal:

using (conn = OpenConnection())
{
    using (tran = conn.BeginTransaction())
    {
        // Do stuff
    }
}

Now some users are in stationary mode, and they just close the application, while the application has an active transaction in the background thread. Our database administrators have found that these transactions are still active in the database for a few more minutes or even longer, which is a problem as transactional data locks open.

So what happens to streams and disposable objects inside these streams when the user decides to close the application? Themes are created using methods Task.StartNew().

+4
source share
2 answers

Tasks

Front and rear streams:

the background thread does not support a running managed runtime. Once all the foreground threads have been stopped in a managed process (where the .exe file is a managed assembly), the system stops all background threads and shuts down.

This also applies to threads from the thread pool, which are used by default when starting a new task without specifying another option:

Task planners

.NET Framework 4 ThreadPool

:

, ( , IsThreadPoolThread ) .

, . , , :

static void Main(string[] args)
{
    Task.Factory.StartNew(Method);
    Task.Delay(1000);
}

static void Method()
{
    try
    {
        while (true) { }
    }
    finally
    {
        File.WriteAllText(@"C:\Polygon\Test.txt", "test");
    }
}

, .

ThreadAbortException -

.NET , ThreadAbortException, , :

CLR , , Thread.Abort.

Process.Exited event -

, , :

var myProcess = new Process();
myProcess.EnableRaisingEvents = true;
myProcess.Exited += new EventHandler(CleanUp);

.

AppDomain.CurrentDomain.ProcessExit -

, Avneesh, :

static void Main(string[] args)
{
    AppDomain.CurrentDomain.ProcessExit += CleanUp;

    Task.Factory.StartNew(Method);
    Task.Delay(1000);
}

static void Method()
{
    try
    {
        while (true) { }
    }
    finally
    {
        CleanUp(null, EventArgs.Empty);
    }
}

static void CleanUp(object sender, EventArgs args)
{
    File.WriteAllText(@"C:\Polygon\Test.txt", "test");
}

, rosources, :

  • .
  • , , .
  • .
  • .
  • .
  • .

:

  • ExitProcess. , CRT (CRT) ExitProcess, .
  • .
  • TerminateProcess .
  • ExitProcess, CTRL + C CTRL + BREAK.
  • .

DB

- , , , . , .

#:

SqlConnection connection = new SqlConnection("Data Source=.;Initial Catalog=[database_name];Integrated Security=True");
connection.Open();
Debugger.Launch();
connection.Close();
connection.Dispose();

T-SQL :

SELECT COUNT(*) FROM sys.dm_exec_sessions
WHERE nt_user_name = '[user_name]' AND program_name = '.Net SqlClient Data Provider'

, . , , . - , - , .

0

, Task.StartNew . , , processExit, , , , .

AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
+1

Source: https://habr.com/ru/post/1543980/


All Articles