Visual Studio保持在调试会话期间打开的文件夹上的句柄

时间:2018-10-01 08:17:16

标签: c# .net wpf visual-studio-2017 locking

我的应用程序在文件夹中打开一个XML文件以反序列化其内容。我释放了所有内容,但devenv仍然在包含的文件夹上保持句柄。问题是:我将第3方程序作为子进程打开,由于它们抱怨无法删除文件夹,因此它们的执行将失败。

这是我在应用程序中用来打开文件并反序列化XML内容的代码:

XmlConfig result = null;
XmlSerializer serializer = new XmlSerializer(typeof(XmlConfig));

using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
    using (StreamReader sr = new StreamReader(fs))
    {
        result = (XmlConfig)serializer.Deserialize(sr);
    }
}

return result;

之前,我没有使用FileStream,而只使用了StreamReader,但是结果是相同的。

如果发生错误,则发生错误:

  • 我从Visual Studio中启动调试会话
  • 我从输出文件夹运行应用程序,并在运行上面的代码之前附加调试器
  • 我从输出文件夹运行该应用程序,并且没有附加调试器,但是之前发生过错误

如果发生以下情况,则不会发生错误:

  • 我从输出文件夹运行该应用程序而没有附加任何调试器
  • 我从输出文件夹中运行应用程序,并在运行上面的代码后附加调试器

我正在运行VS Professional 2017 15.8.4。作为管理员(因为该应用程序必须具有管理员权限运行)是WPF项目,.Net版本4.6。

关于该主题,我能找到的所有内容都是关于由于Visual Studio锁定binobj文件夹中的某些dll文件而无法生成的。那与我的问题不符。

这里发生的事情以及更重要的是:我该如何解决该问题?

编辑:

这是我从子进程中收到的错误消息:

devenx.exe   pid: 8612   type: file   1388: C:\lockedfolder

我还用Unlocker进行了确认:

unlocker showing the folder is locked by devenv.exe

1 个答案:

答案 0 :(得分:1)

因此,当我被问到我要提出我的评论作为答案时。 大的免责声明:这个问题本身对我仍然是个困扰,因为我无法尽最大努力以任何形式复制它。

我整理了一个小测试程序:

示例

class Program
{
    public static string filepath = "test.xml";

    static void Main(string[] args)
    {
        Serialize();

        Console.WriteLine(Deserialize().Test);

        Console.ReadKey(true);
    }

    private static XmlConfig Deserialize()
    {
        XmlConfig result = null;
        XmlSerializer serializer = new XmlSerializer(typeof(XmlConfig));

        using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            using (StreamReader sr = new StreamReader(fs))
            {
                result = (XmlConfig)serializer.Deserialize(sr);
            }
        }

        return result;
    }

    private static void Serialize()
    {
        using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate))
        {
            XmlSerializer serializer = new XmlSerializer(typeof(XmlConfig));
            serializer.Serialize(fs, new XmlConfig());
        }
    }
}

public class XmlConfig
{
    public string Test { get; set; } = "Teststring";
}

如果问题出在代码中,则该方法不起作用。但是它执行得很好,没有任何问题。调试/发布,带有/不带有附加的调试器,VS作为Admin /非管理员。

建议

因此,这是我的建议,似乎可以帮助解决在使用流/序列化时我总是建议尝试的问题:

  • 即使FileStream之类的流实现IDisposable,并且在using块中使用时也应刷新+关闭该流,尝试手动刷新和/或关闭它们。有时可以做到这一点(特别是在使用COM端口时)

  • 始终尝试将局部变量限制在可能的最小范围内(即,需要在使用它的内部移动Serializer初始化。

  • 更少的配置>更多的配置,同时尽可能降低复杂性(在我的示例中,此比较Serialize()Deserialize()