从网络驱动器启动的c# .net4应用程序需要很长时间才能加载

发布于 2024-10-20 08:57:16 字数 663 浏览 1 评论 0原文

让我更好地解释我的情况。我想从网络驱动器启动 .exe。我注意到,如果您检查 Win XP 任务管理器,带有 1 个组件(进度条)的小型 .net 4 窗体会占用大约 20MB 的内存。因此,启动画面加载后,它会占用任务栏中大约 20MB 的内存。

因此,如果 .exe 从网络驱动器启动,客户端计算机必须等待,直到将整个表单加载到内存中,然后才会显示。大约需要 2-3 分钟。所以它必须等待 20mb 加载。从网络驱动器启动 .exe 时立即显示启动屏幕的最佳方法是什么?假设不是等待 20MB 完全下载,是否可以在仅下载到客户端内存中少于 1MB 时显示启动屏幕?您能否提供有关如何执行此操作的建议?

我通过查看客户端计算机上的任务管理器对此进行了检查,直到 .exe 达到大约 20 MB,然后才会显示初始表单。然后它会等到 .exe 达到大约 40MB 时才显示主窗体。我希望从网络驱动器启动 exe 后不到两秒即可显示启动画面,以便用户知道 exe 将在大约 2-3 分钟内完成加载。那么如何实现这一目标呢?

顺便说一句,加载需要很长时间,因为客户端计算机驻留在异地,并且有一个 VPN 将计算机连接到中央文件服务器。这就是为什么加载需要一段时间,因为上传链接最多 1Mb。但是,一旦 .exe 完成加载,就不会出现任何缓慢的情况。最好的方法是使用终端服务或 Citrix。但目前这不是一个选择。或者在客户端计算机上安装每个 .exe,但我不想走这条路。

Let me better explain my scenario. I would like to launch the .exe from a network drive. I have noticed that a small .net 4 form with 1 component (progress bar) takes about 20mb of memory if you check in the Win XP task manager. Hence, once the splash form is loaded it is taking about 20mb of memory in the taskbar.

So if the .exe is launched from a network drive the client machine has to wait until it has loaded the entire form into memory and then it show up. Which is taking about 2-3 minutes. So it has to wait for the 20mb to load. What would be the best method to display a splash screen immediately when launching the .exe from a network drive? Say instead of waiting for the 20MB to fully download, is it possible to display the splash screen when only less than 1mb has been downloaded into the client memory? Could you provide suggestions on how to do this?

I have checked this out by looking at the task manager on the client machine and until the .exe reaches about 20 MB then the splash form is displayed. Then it waits until the .exe reaches about 40MB to display the main form. I would like the splash to display in less than two seconds from when the exe is launched from the network drive so the user knows the exe will finish loading in about 2-3 minutes. So how to achieve this?

By the way, it takes a long time to load because the client machines reside off site and there is a VPN that connects the machines to the central file server. That is why the loading is taking a while because the upload link is at most 1Mb. But once the .exe has finished loading there is no slowness. The best way would be to have terminal services or citrix. But this is not an option for now. Or install each .exe at the client machine but i would prefer not to go down that path.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

冰魂雪魄 2024-10-27 08:57:16

查看 ClickOnce 部署。潜在地,它将允许您保留单个网络副本以便于部署,但将避免客户端下载应用程序,除非它已更新。

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

Have a look at ClickOnce deployment. Potentially, it will allow you to keep your single network copy for ease of deployment, but will save the clients from downloading the application unless it's been updated.

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

不交电费瞎发啥光 2024-10-27 08:57:16

您可能会考虑构建第二个应用程序,该应用程序不执行任何操作,但:

  1. 显示启动屏幕

  2. 启动指向远程exe的新Windows进程。

-

我认为这个问题包含您需要的代码的近似值:

如何知道一个winform何时被Process.Start加载?

You might consider building a second application that does nothing but:

  1. display the splash screen

  2. launch a new Windows Process pointing to the remote exe.

-

I think this question contains an approximation of the code you would need:

How know when a winform is loaded by Process.Start?

不一样的天空 2024-10-27 08:57:16

任务管理器进程选项卡中的内存使用仅是本地的,不是从联网计算机下载的!当您从网络驱动器加载应用程序时,它仅下载可执行文件并在本地执行;这就是每个操作系统一直以来的做法,它不是在服务器上执行并进行流式传输。

我这里有一个时事通讯发送应用程序,例如,15kb exe,加载时使用 4.3mb 内存(数据列表很大,这是预期的)

通过 VPN 从美国的服务器加载到我的本地计算机(我在澳大利亚的一台机器上) ADSL 1,512 链接...太慢了!)它在大约 1-2 秒内加载应用程序,我无法在 1 秒内下载 4.3mb...我希望:)

那么你能做什么你的问题?

如果可执行文件很大并且包含嵌入式资源(图像、视频、列表、XML 等)...您可以将它们制作为外部文件并为用户显示加载窗口,也许也可以在本地缓存文件,因此只需要完成一次,启动应用程序就很快。可以通过应用程序检查和重新下载对资源的更改

如果应用程序可执行文件很小并且没有外部文件/资源​​被访问(在网络文件夹中或在线),那么您只是需要管理一些网络问题:)

The memory use in the task manager process tab is local only and is not downloaded from the networked computer! When you load an application from a network drive it downloads the executable only and executes it locally; this is how every OS has always done it, it is NOT executed on the server and streamed.

I have a newsletter sending application here for example, 15kb exe, 4.3mb in ram use when loaded (large lists of data so that's expected)

Loaded from a server in the USA via VPN to my local machine (i'm in Australia on a ADSL 1,512 link... so ULTRA slow!) it loads the application in ~1-2 second(s) and there is no way i can download 4.3mb in 1 second... i wish :)

So what can you do about your problem?

If the executable is huge and packed with embedded resources (images, videos, list's, XML etc)... you can make them external files instead and show a loading window for the user, perhaps cache files locally too so it only needs to be done once and launching the application is then quick. Changes to resources can be checked and re-downloaded via the application

If the application executable is small and there are no external files/resources being accessed either (in the networked folder or online) then you simply have some network problems to manage :)

风蛊 2024-10-27 08:57:16

.Net 运行时仅在需要时加载程序集 - 如果您使可执行文件尽可能小(只是显示启动屏幕所需的最小限度)并将其余代码放入更大的程序集中,那么理论上您的启动屏幕在需要加载较大的组件之前可以非常快速地显示。

实现此目标的关键是了解 .Net 框架何时尝试加载程序集 - 更准确地说,它将在开始执行引用该程序集中包含的类型的任何方法之前加载程序集。尝试使用以下程序进行实验以更好地理解这一点:

// 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();
}

另请注意,这将发生在主/UI 线程上,因此在加载较大的程序集时,您的启动屏幕没有响应 - 如果这是不可接受的,那么您需要重构上述内容,以便包含 MainForm 引用的方法位于异步线程中。

The .Net runtime only loads assemblies as they are needed - if you keep your executable as small as possible (just the bare minimun required to display a splash screen) and put the rest of your code into a larger assemply then in theory your splash screen can be shown very quickly before the larger assembly needs to be loaded.

The key to achieving this is understanding when the .Net framework will attempt to load an assembly - more precisely it will load an assembly just before it begins executing any method that references a type contained in that assembly. Try experimenting with the following program to understand this better:

// 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
{

}

Armed with this knowledge we now know that in order to get our splash screen to display before loading the second larger assembly we need to make sure that our splash screen is shown before we execute any method that references any type in our larger assembly - its difficult for me to test this, but if we have a fairly standard splash screen:

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

Then the first point that we should reference any types in the larger assembly should be in something like the SplashScreen_Shown event, something like:

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

Also note that this will happen on the main / UI thread and so your splash screen is unresponsive while the larger assembly is being loaded - if this is unacceptable then you need to refactor the above so that the method containing the MainForm reference is in an asynchronous thread.

箜明 2024-10-27 08:57:16

嘿,谢谢你的回答。根据您的建议,我考虑了以下解决方案。 A 构建了一个控制台应用程序,当您从网络驱动器启动它时,它启动得非常快。不到两秒。这个控制台应用程序将是我的启动屏幕,虽然不漂亮,但至少用户会知道正在发生某些事情。控制台 exe 将启动我想要真正加载的 .exe,至少用户会知道它正在加载,并且需要几分钟才能加载。如果可能的话,控制台应用程序将显示剩余时间。我现在只需弄清楚如何使用控制台应用程序来执行此操作。一旦主 .exe 加载完毕,我就必须关闭控制台应用程序。

有人知道如何从控制台应用程序执行此操作吗?

Hey thanks for your answers. After your suggestions i have thought about the following solution. A have built a console application that when you launch it from the network drive, it launches very quick. In under two seconds. This console application will be my splash screen, not pretty but at least the user will know that something is happening. The console exe will launch the .exe i want to really load and at least the user will know that its loading and will take several minutes to load. If possible the console application will display how much time is left. I just gotta now figure out how to do this using a console application. Once the main .exe has loaded I then have to close the console application.

Any one know how to do this from a console application?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文