Это интересный крайний случай, из-за того, как работает asyn c.
Давайте рассмотрим эти методы тестирования:
private void Button_Click(object sender, RoutedEventArgs e)
{
ShowAssembly();
ShowAssemblyAsync();
}
private void ShowAssembly()
{
Assembly assembly = Assembly.GetCallingAssembly();
MessageBox.Show(assembly.FullName);
}
private async void ShowAssemblyAsync()
{
Assembly assembly = Assembly.GetCallingAssembly();
MessageBox.Show(assembly.FullName);
}
В ShowAssembly
будет отображаться имя основной сборки вашей программы. В ShowAssemblyAsync
будет отображаться «mscorlib». Что происходит?
Если вы установите точку останова в ShowAssembly
и ShowAssemblyAsync
в Visual Studio, вы получите следующие стеки вызовов:
DesktopClient.exe!DesktopClient.MainWindow.ShowAssembly() Line 119 C#
DesktopClient.exe!DesktopClient.MainWindow.Button_Click(object sender, System.Windows.RoutedEventArgs e) Line 109 C#
DesktopClient.exe!DesktopClient.MainWindow.ShowAssemblyAsync() Line 128 C#
DesktopClient.exe!DesktopClient.MainWindow.Button_Click(object sender, System.Windows.RoutedEventArgs e) Line 110 C#
Ничего подозрительного там нет , Тем не менее, Visual Studio лжет вам. Если вместо этого я использую отладчик более низкого уровня (в данном случае WinDbg), я получаю следующие стеки вызовов:
00efe58c 07cf423b DesktopClient.MainWindow.ShowAssembly()
00efe5a8 07cf41dc DesktopClient.MainWindow.Button_Click(System.Object, System.Windows.RoutedEventArgs)
00efe4d8 07cf43c6 DesktopClient.MainWindow+d__10.MoveNext()
00efe51c 5ddaa48d System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start[[System.__Canon, mscorlib]](System.__Canon ByRef)
00efe574 07cf4317 DesktopClient.MainWindow.ShowAssemblyAsync()
00efe5a8 07cf41e6 DesktopClient.MainWindow.ButtonPlus_Click(System.Object, System.Windows.RoutedEventArgs)
Вы видите, что стэк вызовов из ShowAssemblyAsync
полностью изменился после применения ключевое слово asyn c (Visual Studio скрывает это, чтобы упростить отладку). Одним из следствий этого является то, что метод теперь вызывается System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start
, и поэтому мы получаем «mscorlib» при извлечении вызывающей сборки.
В качестве исправления вы можете использовать Assembly.GetExecutingAssembly
(при условии, что ваш CopyFileToDestinationAsync
метод находится в правильной сборке) или явно указывайте целевую сборку: typeof(MainWindow).Assembly
. Или, как и вы, просто извлеките поток перед вызовом метода.
Еще один способ - ввести дополнительный не асинхронный метод c, чтобы просто получить сборку перед вызовом реальной асинхронной реализации c. :
private Task CopyFileToDestinationAsync(string nameSpace,string outDirectory, string internalPath, string resourceName)
{
Assembly assembly = Assembly.GetCallingAssembly();
return CopyFileToDestinationAsync(assembly, nameSpace, outDirectory, internalPath, resourceName);
}
private async Task CopyFileToDestinationAsync(Assembly assembly string nameSpace,string outDirectory, string internalPath, string resourceName)
{
using (Stream stream = assembly.GetManifestResourceStream(nameSpace + "." + (internalPath == "" ? "" : internalPath + ".") + resourceName))
{
// ...
}
}