winforms 是否可以在C#中释放库?

0pizxfdo  于 2022-11-17  发布在  C#
关注(0)|答案(1)|浏览(188)

我目前正在Visual Studio Community 2022上开发一个WinForms .NET应用程序。我创建的一个名为UpdaterLibrary的库遇到了一些问题。该库包含更新应用程序所需的所有方法,但正因为如此,我无法用它自己的代码更新该文件。因为这意味着删除文件并用新的文件替换它。我所做的就是使用所有的方法,我可以从那个库中复制一些代码(我为更新应用程序文件而创建的delete和copy方法),这样我就可以从更新路径中删除和复制新的UpdaterLibrary。问题是,如果我使用该库,应用程序不会关闭文件,即使我释放该类或将其放入using语句中也是如此。我的问题是:有没有办法在使用完文件后关闭/释放它?代码如下:

private static async Task CheckForUpdatesForUpdaterLibrary()
        {
            await Task.Run(async () =>
            {
                try
                {
                    UpdaterLibrary.UpdaterClass updater = await UpdaterLibrary.UpdaterClass.CreateInstance();
                    Version localUpdaterLibraryVersion = await updater.GetFileVersion("UpdaterLibrary.dll", false);

                    if (await updater.VersionIsLower("UpdaterLibrary.dll", localUpdaterLibraryVersion))
                    {
                        updater.Dispose();
                        await UpdateUpdaterLibrary();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Hubo un error al actualizar la aplicación. Vuelva a intentarlo más tarde. \n{ex.Message} \n\n {ex.StackTrace}");
                }
            });
        }

private static async Task UpdateUpdaterLibrary()
        {
            await Task.Run(async () =>
            {
                if (await UpdaterLibrary.UpdaterClass.IsRunningAsAdmin())
                {
                    if (!Directory.Exists(UpdatePath))
                    {
                        Directory.CreateDirectory(UpdatePath);
                    }
                    MessageBox.Show("Hay una actualización disponible para la librería del actualizador de la aplicación. Espere un momento mientras se instala la actualización.");
                    List<string> updaterLibraryList = new List<string>
                    {
                        "UpdaterLibrary.dll"
                    };
                    await UpdateFiles(updaterLibraryList);
                }
                else
                {
                    MessageBox.Show("Hay una actualización disponible para la librería del actualizador de la aplicación. Se reiniciará la aplicación y se le pediran permisos para poder actualizarlo.");
                    await UpdaterLibrary.UpdaterClass.RunAsAdmin();
                    Environment.Exit(0);
                }
            });
        }

public static async Task UpdateFiles(List<string> filesToUpdate)
        {
            await Task.Run(async () =>
            {
                HttpClient client = await SetClient(new Version("1.0.0"), token);
                await DownloadNewFiles(filesToUpdate, client);
                await DeleteOldFiles(filesToUpdate);
                await CopyFiles(filesToUpdate);
            });
        }

public static async Task DownloadNewFiles(List<string> newFiles, HttpClient client)
        {
            await Task.Run(async () =>
            {
                string updatePath = UpdatePath;

                JArray contentArray = await GetGitHubContents(client);
                foreach (JObject contentItem in contentArray.Cast<JObject>())
                {
                    string name = (string)contentItem["name"];
                    if (newFiles.Contains(name))
                    {
                        string downloadUrl = (string)contentItem["download_url"];
                        byte[] downloadBytes = await client.GetByteArrayAsync(downloadUrl);
                        string filePath = $@"{updatePath}\{name}";
                        File.WriteAllBytes(filePath, downloadBytes);
                    }
                }
            });
        }

public static async Task DeleteOldFiles(List<string> filesToDelete)
        {
            await Task.Run(() =>
            {
                string path = AppPath;

                foreach (string file in filesToDelete)
                {
                    string fileName = $@"{path}\{file}";
                    File.Delete(fileName);
                }
            });
        }

UpdaterLibrary里面的代码其实并不重要,它运行得很好。我不知道它是否没有disposing,也许是因为我只使用了静态方法,但我不这么认为。

bvhaajcl

bvhaajcl1#

您问题:“是否可以在C#中释放库”
答:
否,因为内存回收行程无法分割组件内的执行严修所持有的内存。
一些细节:
如果框架像c / c++那样支持卸载链接的程序集,垃圾收集器在保持对象依赖树的完整性方面将有一个大问题。这就是为什么不可能在托管应用程序进程中卸载已加载的程序集的(简短)原因。
解决方法:
但是,正如他在评论中所说的,你可以做一个App-Domain,它或多或少是一个子进程。缺点是,就像每个进程间的通信一样:这是一个不同的过程,如果要在它们之间交换数据,您需要处理它。

相关问题