Приложение c # .net4, запущенное с сетевого диска, долго загружается - PullRequest
2 голосов
/ 04 марта 2011

Позвольте мне лучше объяснить мой сценарий. Я хотел бы запустить .exe с сетевого диска. Я заметил, что маленькая форма .net 4 с 1 компонентом (индикатор выполнения) занимает около 20 МБ памяти, если вы включите диспетчер задач Win XP. Следовательно, после загрузки формы-заставки она занимает около 20 МБ памяти на панели задач.

Таким образом, если .exe запускается с сетевого диска, клиентский компьютер должен подождать, пока он загрузит всю форму в память, а затем он появится. Что занимает около 2-3 минут. Так что приходится ждать 20 Мб для загрузки. Каков наилучший способ немедленного отображения заставки при запуске .exe с сетевого диска? Скажем, вместо ожидания полной загрузки 20 МБ, возможно ли отобразить заставку, когда в память клиента загружено менее 1 МБ? Не могли бы вы дать предложения о том, как это сделать?

Я проверил это, посмотрев на диспетчер задач на клиентском компьютере, и, пока .exe не достигнет примерно 20 МБ, отобразится всплывающая форма. Затем он ждет, пока .exe не достигнет около 40 МБ для отображения основной формы. Я хотел бы, чтобы всплеск отображался менее чем через две секунды после запуска exe-файла с сетевого диска, чтобы пользователь знал, что exe завершит загрузку примерно через 2-3 минуты. Так как этого добиться?

Кстати, загрузка занимает много времени, потому что клиентские машины находятся вне сайта, и есть VPN, которая соединяет машины с центральным файловым сервером. Вот почему загрузка занимает некоторое время, потому что ссылка для загрузки составляет не более 1 МБ. Но как только .exe завершит загрузку, медлительности не будет. Лучшим способом было бы иметь терминальные услуги или Citrix. Но это не вариант сейчас. Или установите каждый .exe на клиентский компьютер, но я бы предпочел не идти по этому пути.

Ответы [ 5 ]

1 голос
/ 04 марта 2011

Посмотрите на развертывание ClickOnce.Потенциально, это позволит вам сохранить единую сетевую копию для простоты развертывания, но спасет клиентов от загрузки приложения, если оно не было обновлено.

http://msdn.microsoft.com/en-us/library/t71a733d

0 голосов
/ 05 марта 2011

Эй, спасибо за ваши ответы.После ваших предложений я подумал о следующем решении.Мы создали консольное приложение, которое при запуске с сетевого диска запускается очень быстро.Менее чем за две секунды.Это консольное приложение будет моим заставкой, не очень, но, по крайней мере, пользователь будет знать, что что-то происходит.Exe консоли запустит .exe, который я действительно хочу загрузить, и, по крайней мере, пользователь будет знать, что он загружается, и загрузка займет несколько минут.Если возможно, консольное приложение покажет, сколько времени осталось.Я просто должен сейчас выяснить, как сделать это с помощью консольного приложения.После загрузки основного .exe-файла мне нужно закрыть консольное приложение.

Кто-нибудь знает, как это сделать из консольного приложения?

0 голосов
/ 04 марта 2011

Среда выполнения .Net загружает сборки только по мере необходимости - если вы сохраняете свой исполняемый файл настолько маленьким, насколько это возможно (всего лишь минимальный минимум, необходимый для отображения заставки), и помещаете оставшуюся часть кода в более крупную сборку, чем в теории Ваш заставочный экран может быть показан очень быстро, прежде чем загрузится большая сборка.

Ключом к достижению этого является понимание того, когда .Net Framework будет пытаться загрузить сборку - точнее, он загрузит сборку непосредственно перед тем, как начнет выполнять любой метод, который ссылается на тип, содержащийся в этой сборке. Попробуйте поэкспериментировать со следующей программой, чтобы лучше это понять:

// Contained in FirstAssembly.exe
class Program
{
    static void Main()
    {
        PrintLoadedAssemblies("start of Main");
        innerMain();
    }

    static void innerMain()
    {
        PrintLoadedAssemblies("start of innerMain");
        OtherClass obj;
    }

    static void PrintLoadedAssemblies(string point)
    {
        Console.WriteLine("Loaded assemblies at {0}", point);
        foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
        {
            Console.WriteLine(assembly.FullName);
        }
    }
}

// Contained in OtherAssembly.dll
class OtherClass
{

}

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

static void Main()
{
    Application.Run(new SplashScreen());
}

Тогда первая точка, в которой мы должны ссылаться на любые типы в большей сборке, должна быть в чем-то вроде SplashScreen_Shown, что-то вроде:

void SplashScreen_Shown(object sender, EventArgs e)
{
    (new MainForm()).Show();
    this.Hide();
}

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

0 голосов
/ 04 марта 2011

Использование памяти на вкладке процесса диспетчера задач носит локальный характер и не загружается с сетевого компьютера! Когда вы загружаете приложение с сетевого диска, оно загружает только исполняемый файл и выполняет его локально; так всегда делали все ОС, это НЕ выполняется на сервере и не транслируется.

У меня есть приложение для отправки рассылки, например, 15kb exe, 4.3 МБ в оперативной памяти при загрузке (большие списки данных, так что это ожидаемо)

Загруженный с сервера в США через VPN на мою локальную машину (я нахожусь в Австралии по каналу ADSL 1,512 ... так что ULTRA медленно!), Он загружает приложение через ~ 1-2 секунды и там я не могу скачать 4.3mb за 1 секунду ... я хочу:)

Так что вы можете сделать с вашей проблемой?

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

Если исполняемый файл приложения невелик и нет внешних файлов / ресурсов, к которым осуществляется доступ (ни в сетевой папке, ни в сети), то вам просто нужно решить некоторые проблемы с сетью:)

0 голосов
/ 04 марта 2011

Вы можете подумать о создании второго приложения, которое ничего не делает, кроме:

  1. отображение заставки

  2. запустить новый процесс Windows, указывающий на удаленный exe.

-

Я думаю, что этот вопрос содержит приблизительный код, который вам понадобится:

Как узнать, когда Win.form загружается Process.Start?

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