1

I read this post, in my code everything seems to be proper!
I'm using Dockpanel suite to save & load layout. problem here is in saving layout. while debugging from visual studio, when i close winform(save layout) it takes long time(10 seconds) then VS stops debugging session.
if i run exe directly, after closing application(need to click on 'x' button twice!) i receive the following error

See the end of this message for details on invoking just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.IO.IOException: The process cannot access the file 'C:\Users\Admin\Documents\Visual Studio 2015\Projects\test\Release\Layout.config' because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode)
at InsightRealityv2.Main.Main_FormClosing(Object sender, FormClosingEventArgs e) in c:\users\Admin\documents\visual studio 2015\projects\test\insight reality v2\main.h:line 573
.
.
.

now, According to the error message "Layout.config" is still open. but i'm closing FileStream. below is my code (function called when form loads)

Void load_layout()
{   
    System::String^ path = Path::Combine(Path::GetDirectoryName(Application::ExecutablePath), "Layout.config");
    if (File::Exists(path)) 
    {
        FileStream ^fs1 = gcnew FileStream(path, FileMode::Open, FileAccess::Read);
        Stream ^s1 = fs1;
        DeserializeDockContent ^m_deserializeDockContent = gcnew DeserializeDockContent(this, &Main::GetContentFromPersistString);
        dockPanel1->LoadFromXml(path, m_deserializeDockContent);
        fs1->Close();
        s1->Close();
    }
}

below code is called when form closing event triggers

Void Save_Layout()
{
   System::String^ path = Path::Combine(Path::GetDirectoryName(Application::ExecutablePath), "Layout.config");
   FileStream ^fs = gcnew FileStream(path, FileMode::Create);
   Stream ^s = fs;
   dockPanel1->SaveAsXml(s, System::Text::Encoding::Unicode, false);
   fs->Close();
   s->Close();  
}

both the function is been called only once from same UI thread.

Community
  • 1
  • 1
Prakash M
  • 659
  • 1
  • 12
  • 36
  • This code is not exception-safe. With pretty decent odds that you use try/catch-em-all in the caller so you can't see that it failed to load the file, threw an exception and thus failed to close the file. Use *stack semantics* or the `finally` keyword. – Hans Passant Nov 18 '16 at 11:52
  • @HansPassant, Thanks for your comment. i wrapped load_layout block with try catch. it didn't help. its closing FileStream properly itself! – Prakash M Nov 18 '16 at 15:16
  • 1
    Well, I guessed you used try/catch in the caller. The problem is that it **doesn't** close the FileStream. The exception bypasses your fs->Close() call. Google "stack semantics", take the first hit. – Hans Passant Nov 18 '16 at 15:20

0 Answers0