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