Почему File.Open такой дорогой? - PullRequest
3 голосов
/ 16 июня 2011

У меня есть следующий код:

try
{
    string fileName = imageQueue.Dequeue();
    FileStream fileStream = File.Open(
        fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    Bitmap bitmap = new Bitmap(fileStream);
    Image picture = (Image)bitmap;
    pb.Tag = fileName;
    pb.Image = picture;
    return true;
}
catch (Exception ex)
{
    errorCount++;
    //If another PC has this image open it will error
    return false;
}

Поскольку эта программа работает на 2 компьютерах, имеющих доступ к одной и той же папке, чтобы забрать файлы, она выдаст исключение, если файл открыт, а затем перейдет к следующему файлу в своем списке.

Когда я открываю приложение на 2 компьютерах одновременно, первый компьютер открывает изображение, а второй - нет. Я показываю сразу 4 изображения на экране, но отладка показывает, что у второго компьютера не хватает 10,5 секунд для открытия 4 файлов, прежде чем он находит тот, который может открыть.

Почему это так дорого и что я могу сделать, чтобы ускорить его?

ОБНОВЛЕНИЕ: Я предоставляю ему эксклюзивный доступ, потому что я хочу, чтобы приложения отображали уникальные изображения, чтобы ПК1 отображал изображения 1,2,3,4, а ПК - 5,6,7,8, потому что он не может получить доступ к 1,2,3,4. Затем я также освобождаю файловый поток, как только с ним покончено, и в последний момент, чтобы другие приложения не пытались его открыть.

Ответы [ 4 ]

4 голосов
/ 16 июня 2011

Вы открываете файл как FileAccess.ReadWrite (кажется, вы не пишете).Вы говорите ему, что не хотите делиться файлом, FileShare.None, (поэтому первый компьютер, получивший файл, выигрывает).

Кроме того, вы никогда не закрываете поток.Таким образом, компьютер, который получает файл, сначала удерживает его, пока сборщик мусора не закроет поток для вас.Когда вы получите свой поток, оберните его в блок using, чтобы файл автоматически закрылся:

using (FileStream fileStream = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
{
    // Do stuff with the filestream
}
// The stream will be closed when the closing brace is passed.
3 голосов
/ 16 июня 2011

После редактирования

Поскольку вы хотите, чтобы они были заблокированы, вы можете рассмотреть возможность создания облегченной базы данных (sqllite, xml и т. Д.), Которую можно использовать для пометки файла как «используемого». Затем в методе вы должны проверить, если он используется. Это устранит необходимость ожидания истечения времени ожидания File.Open при попытке открыть заблокированный файл.

Оригинал

Полагаю, я должен был ответить, а не комментировать ...

try
{
    string fileName = imageQueue.Dequeue();
    using( FileStream fileStream = File.Open( fileName, FileMode.Open, FileAccess.Read, FileShare.Read) )
    {
        Bitmap bitmap = new Bitmap(fileStream);
        Image picture = (Image)bitmap;
        pb.Tag = fileName;
        pb.Image = picture;
    }

    return true;
}
catch (Exception ex)
{
    errorCount++;
    //If another PC has this image open it will error
    return false;
}
3 голосов
/ 16 июня 2011

Я не могу ответить однозначно, но мое лучшее предложение состоит в том, чтобы что-то в системе, либо в классах .net framework, либо в файловой системе, реализовывало механизм тайм-аута / повтора в случае сбоев при совместном использовании файлов.Это объясняет чрезмерную задержку, о которой вы сообщаете.

0 голосов
/ 16 июня 2011

Вы пробовали экспериментировать с этими свойствами потока? Вы можете сократить время ожидания, если ничего больше:

http://msdn.microsoft.com/en-us/library/470w48b4.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...