Решение с более чем 100 проектами принимает пять минут для создания

Короткий ответ: они не становятся удаленными.

длинный ответ: управляемое Path.GetTempFileName() вызовы метода собственный метод Win32API GetTempFileName() , как это:

//actual .NET 2.0 decompiled code 
// .NET Reflector rocks for looking at plumbing
public static string GetTempFileName()
{
    string tempPath = GetTempPath();
    new FileIOPermission(FileIOPermissionAccess.Write, tempPath).Demand();
    StringBuilder tmpFileName = new StringBuilder(260);
    if (Win32Native.GetTempFileName(tempPath, "tmp", 0, tmpFileName) == 0)
    {
        __Error.WinIOError();
    }
    return tmpFileName.ToString();
}

документация для состояний собственного метода:

Временные файлы, имена которых были созданы этой функцией, автоматически не удалены. Для удаления этих файлов называют DeleteFile.

я нашел большую статью названной "Те противные временные файлы" (Заархивированный октябрь 2007), который начинает с основ и касается некоторых менее очевидных проблем обработки временных файлов, как:

  • , Как удостовериться, файл удален (даже если сбои приложения! подсказка: FileOption.DeleteOnClose и позволяют ядру иметь дело с ним)
  • , Как получить корректную политику кэширования для файла, для улучшения производительности (подсказка: FileAttributes.Temporary )
  • , Как удостовериться, содержание файла остается безопасным, потому что:
    • имя файла еще более предсказуемо с управляемым методом, чем с неуправляемым
    • , временный файл создается, тогда закрылся , тогда Вы получаете путь к нему (только для открытия его снова), таким образом оставляя небольшой удобный момент для вредоносного кода / пользователи для угона файла.

Код C# от статьи:

using System;
using System.IO;
using System.Security.Permissions;
using System.Security.Principal;
using System.Security.AccessControl;

public static class PathUtility
{
    private const int defaultBufferSize = 0x1000; // 4KB

#region GetSecureDeleteOnCloseTempFileStream

    /// 
    /// Creates a unique, randomly named, secure, zero-byte temporary file on disk, which is automatically deleted when it is no longer in use. Returns the opened file stream.
    /// 
    /// 
    /// The generated file name is a cryptographically strong, random string. The file name is guaranteed to be unique to the system's temporary folder.
    /// The  method will raise an  if no unique temporary file name is available. Although this is possible, it is highly improbable. To resolve this error, delete all uneeded temporary files.
    /// The file is created as a zero-byte file in the system's temporary folder.
    /// The file owner is set to the current user. The file security permissions grant full control to the current user only.
    /// The file sharing is set to none.
    /// The file is marked as a temporary file. File systems avoid writing data back to mass storage if sufficient cache memory is available, because an application deletes a temporary file after a handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.
    /// The system deletes the file immediately after it is closed or the  is finalized.
    /// 
    /// The opened  object.
    public static FileStream GetSecureDeleteOnCloseTempFileStream()
    {    
        return GetSecureDeleteOnCloseTempFileStream(defaultBufferSize, FileOptions.DeleteOnClose);    
    }

    /// 
    /// Creates a unique, randomly named, secure, zero-byte temporary file on disk, which is automatically deleted when it is no longer in use. Returns the opened file stream with the specified buffer size.
    /// 
    /// 
    /// The generated file name is a cryptographically strong, random string. The file name is guaranteed to be unique to the system's temporary folder.
    /// The  method will raise an  if no unique temporary file name is available. Although this is possible, it is highly improbable. To resolve this error, delete all uneeded temporary files.
    /// The file is created as a zero-byte file in the system's temporary folder.
    /// The file owner is set to the current user. The file security permissions grant full control to the current user only.
    /// The file sharing is set to none.
    /// The file is marked as a temporary file. File systems avoid writing data back to mass storage if sufficient cache memory is available, because an application deletes a temporary file after a handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.
    /// The system deletes the file immediately after it is closed or the  is finalized.
    /// 
    /// A positive  value greater than 0 indicating the buffer size.
    /// The opened  object.
    public static FileStream GetSecureDeleteOnCloseTempFileStream(int bufferSize)
    {
        return GetSecureDeleteOnCloseTempFileStream(bufferSize, FileOptions.DeleteOnClose);
    }

    /// 
    /// Creates a unique, randomly named, secure, zero-byte temporary file on disk, which is automatically deleted when it is no longer in use. Returns the opened file stream with the specified buffer size and file options.
    ///   
    /// 
    /// The generated file name is a cryptographically strong, random string. The file name is guaranteed to be unique to the system's temporary folder.
    /// The  method will raise an  if no unique temporary file name is available. Although this is possible, it is highly improbable. To resolve this error, delete all uneeded temporary files.
    /// The file is created as a zero-byte file in the system's temporary folder.
    /// The file owner is set to the current user. The file security permissions grant full control to the current user only.
    /// The file sharing is set to none.
    /// The file is marked as a temporary file. File systems avoid writing data back to mass storage if sufficient cache memory is available, because an application deletes a temporary file after a handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.
    /// The system deletes the file immediately after it is closed or the  is finalized.
    /// Use the  parameter to specify additional file options. You can specify  to encrypt the file contents using the current user account. Specify  to enable overlapped I/O when using asynchronous reads and writes.
    /// 
    /// A positive  value greater than 0 indicating the buffer size.
    /// A  value that specifies additional file options.
    /// The opened  object.
    public static FileStream GetSecureDeleteOnCloseTempFileStream(int bufferSize, FileOptions options)
    {    
        FileStream fs = GetSecureFileStream(Path.GetTempPath(), bufferSize, options | FileOptions.DeleteOnClose);

        File.SetAttributes(fs.Name, File.GetAttributes(fs.Name) | FileAttributes.Temporary);

        return fs;    
    }

#endregion

#region GetSecureTempFileStream

    public static FileStream GetSecureTempFileStream()
    {    
        return GetSecureTempFileStream(defaultBufferSize, FileOptions.None);    
    }

    public static FileStream GetSecureTempFileStream(int bufferSize)
    {
        return GetSecureTempFileStream(bufferSize, FileOptions.None);
    }

    public static FileStream GetSecureTempFileStream(int bufferSize, FileOptions options)
    {
        FileStream fs = GetSecureFileStream(Path.GetTempPath(), bufferSize, options);

        File.SetAttributes(fs.Name, File.GetAttributes(fs.Name) | FileAttributes.NotContentIndexed | FileAttributes.Temporary);

        return fs;
    }

    #endregion

#region GetSecureTempFileName

    public static string GetSecureTempFileName()
    {    
        return GetSecureTempFileName(false);    
    }

    public static string GetSecureTempFileName(bool encrypted)
    {    
        using (FileStream fs = GetSecureFileStream(Path.GetTempPath(), defaultBufferSize, encrypted ? FileOptions.Encrypted : FileOptions.None))
        {    
            File.SetAttributes(fs.Name, File.GetAttributes(fs.Name) | FileAttributes.NotContentIndexed | FileAttributes.Temporary);

            return fs.Name;    
        }

    }

#endregion

#region GetSecureFileName

    public static string GetSecureFileName(string path)
    {    
        return GetSecureFileName(path, false);    
    }

    public static string GetSecureFileName(string path, bool encrypted)
    {    
        using (FileStream fs = GetSecureFileStream(path, defaultBufferSize, encrypted ? FileOptions.Encrypted : FileOptions.None))
        {    
            return fs.Name;    
        }    
    }

#endregion

#region GetSecureFileStream

    public static FileStream GetSecureFileStream(string path)
    {    
        return GetSecureFileStream(path, defaultBufferSize, FileOptions.None);    
    }

    public static FileStream GetSecureFileStream(string path, int bufferSize)
    {
        return GetSecureFileStream(path, bufferSize, FileOptions.None);
    }

    public static FileStream GetSecureFileStream(string path, int bufferSize, FileOptions options)
    {    
        if (path == null)
            throw new ArgumentNullException("path");

        if (bufferSize <= 0)
            throw new ArgumentOutOfRangeException("bufferSize");

        if ((options & ~(FileOptions.Asynchronous | FileOptions.DeleteOnClose | FileOptions.Encrypted | FileOptions.RandomAccess | FileOptions.SequentialScan | FileOptions.WriteThrough)) != FileOptions.None)
            throw new ArgumentOutOfRangeException("options");

        new FileIOPermission(FileIOPermissionAccess.Write, path).Demand();

        SecurityIdentifier user = WindowsIdentity.GetCurrent().User;

        FileSecurity fileSecurity = new FileSecurity();

        fileSecurity.AddAccessRule(new FileSystemAccessRule(user, FileSystemRights.FullControl, AccessControlType.Allow));

        fileSecurity.SetAccessRuleProtection(true, false);

        fileSecurity.SetOwner(user);

        // Attempt to create a unique file three times before giving up.
        // It is highly improbable that there will ever be a name clash,
        // therefore we do not check to see if the file first exists.

        for (int attempt = 0; attempt < 3; attempt++)
        {    
            try
            {    
                return new FileStream(Path.Combine(path, Path.GetRandomFileName()),
                                        FileMode.CreateNew, FileSystemRights.FullControl,
                                        FileShare.None, bufferSize, options, fileSecurity);
            }

            catch (IOException)
            {
                if (attempt == 2)
                    throw;
            }

        }

        // This code can never be reached.
        // The compiler thinks otherwise.
        throw new IOException();

    }

#endregion

}

5
задан 3 revs, 2 users 100% 29 September 2009 в 19:35
поделиться

5 ответов

В вашем вопросе нет подробностей, но я полагаю, что сбой - это просто проблема с ресурсами рабочей станции, а не что-либо еще. 100 проектов сами по себе не проблема, если есть веские причины для такого количества, но к тому времени, когда вы дойдете до более чем 10 проектов, я надеюсь, что у вас будет какая-то структура управления для них.

Вам действительно нужно строить все 100 проектов все время? Вы можете отключить отдельные проекты для сборки с помощью диспетчера конфигурации, и вы можете создавать файлы решений с подмножеством общего количества проектов.

Например, у нас есть 36 проектов для одного из корпоративных приложений, с которыми я работаю. Наряду с этим, у нас есть несколько файлов решений и конфигураций, предназначенных для того, чтобы наши разработчики могли загружать только те проекты и конфигурацию, которые им необходимы для работы с заданными подкомпонентами приложения. Другими словами, они загружают только часть из 36 проектов. Наш сервер сборки позаботится о том, чтобы собрать все вместе.

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

9
ответ дан 18 December 2019 в 11:58
поделиться

Все ли они должны строить одновременно? Если нет, вы можете войти в Configuration Manager и выбрать только те, которые вам нужны в настоящее время.

Хотя мне кажется, что 100 проектов в решении - это довольно много. Это действительно необходимо? Можете ли вы разбить его на более мелкие связанные решения, или действительно существует так много проектов, которые взаимозависимы друг от друга?

2
ответ дан 18 December 2019 в 11:58
поделиться

Кажется, ваш вопрос больше связан с дизайном вашего решения, а не с возможностью VS обрабатывать 100 проектов. Вы действительно хотите знать, не является ли тот факт, что ваше решение занимает много времени, запахом кода для «чёрт возьми, мы спроектировали это неправильно».

Если у вас соотношение 1: 1 между сборками «UI» и «Сервером» сборок, они логически одинаковы и могут быть объединены.

На мой взгляд, для сборок модулей CAB / CAG нормально иметь все их зависимости в одной сборке. Если вы намереваетесь разделять код доступа к данным в нескольких модулях, имеет смысл разбить его на отдельную сборку.

Если вы решите, что этот подход не подходит , обычно у нас есть несколько меньших решений , которые позволяют нам тестировать несколько связанных модулей вместе локально во время разработки, но есть одно большое решение, которое построено на наших серверах сборки . Таким образом, длительное время сборки приходится на выделенную машину сборки, а не на наши локальные блоки разработки (это также хороший подход даже для самых маленьких проектов).

3
ответ дан 18 December 2019 в 11:58
поделиться

Вы можете щелкнуть правой кнопкой мыши отдельный проект в обозревателе решений и выбрать вариант сборки только этого проекта. Если в порядке сборки есть какие-либо необходимые проекты, он также построит их, но это позволяет вам создавать только необходимые элементы.

1
ответ дан 18 December 2019 в 11:58
поделиться

Конфигурации решения по умолчанию «Отладка и выпуск» всегда проверяют все проекты и строят те, которые не являются актуальными. Вы можете создать свою собственную конфигурацию решения, отключив опцию сборки для проектов, которые, как вы знаете, не нуждаются в проверке.

0
ответ дан 18 December 2019 в 11:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: