using и Thread.Abort()
От: nikov США http://www.linkedin.com/in/nikov
Дата: 16.08.06 16:52
Оценка:
До недавнего времени был уверен, что конструкция using обеспечивает 100% выполнение метода Dispose. Оказалось, что в некоторых случаях некоторые исключения, такие как ThreadAbortException могут произойти до того, как ссылка на созданный объект будет возвращена вызывающему коду. В приведенном ниже примере поток не закрывается после нескольких итераций.

using System;
using System.IO;
using System.Threading;

public class Program
{
    private static readonly Random _random = new Random();

    public static void Main()
    {
        while (true)
        {
            Thread thread = new Thread(DoWork);
            thread.Start();
            Thread.Sleep(_random.Next(100));
            thread.Abort();
        }
    }

    public static void DoWork()
    {
        while (true)
        {
            using (FileStream fs = new FileStream("temp.txt", FileMode.Create))
            {
                
            }
        }
    }
}



Unhandled Exception: System.IO.IOException: The process cannot access the file 'temp.txt' because it is being used by another process.


Так что же делать? Неужели отказываться от симпатичной конструкции using и, уповая на то, что в блоке finally поток не может быть прерван, писать аццкий код вроде такого:

using System;
using System.IO;
using System.Threading;

public class Program
{
    private static readonly Random _random = new Random();

    public static void Main()
    {
        while (true)
        {
            Thread thread = new Thread(DoWork);
            thread.Start();
            Thread.Sleep(_random.Next(100));
            thread.Abort();
        }
    }

    public static void DoWork()
    {
        while (true)
        {
            FileStream fs = null;
            try
            {
                try
                {
                    Thread.Sleep(0);
                }
                finally
                {
                    fs = new FileStream("temp.txt", FileMode.Create);
                }
            }
            finally
            {
                if(fs != null) ((IDisposable) fs).Dispose();
            }
        }
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.