taji01 taji01 - 14 days ago 6
C# Question

Release the file when application is done using it

I'm using

WinForms
. In my form I have a button that prints all tif images in a directory. I want to tell my application to release the images if the print job is canceled or if the its done printing. I think that FileInfo is probably the problem here. How can i accomplish this task?

List<string> DocPathList = new List<string>();
private int page;

private void btn_Print_Click(object sender, EventArgs e)
{
DirectoryInfo SourceDirectory = new DirectoryInfo(@"C:\image\Shared_Directory\Printing_Folder\");
FileInfo[] Files = SourceDirectory.GetFiles("*.tif"); //Getting Tif files


foreach (FileInfo file in Files)
{
DocPathList.Add(SourceDirectory + file.Name);
}

printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.Show();
}

private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.DrawImage(Image.FromFile(DocPathList[page]), e.MarginBounds);
page++;
e.HasMorePages = page < DocPathList.Count;
}

private void printDocument1_BeginPrint(object sender, PrintEventArgs e)
{
page = 0;
}


If i add this line of code it release the Image. It works if i click on the button once. However, if i want to press the print button the second time
printPreviewDialog1.Show();
throws an error:


Exception thrown: 'System.ObjectDisposedException' in System.Windows.Forms.dll


using (var image = Image.FromFile(DocPathList[page]))
{
e.Graphics.DrawImage(image, e.MarginBounds);
page++;
e.HasMorePages = page < DocPathList.Count;
}


For example, if i cancel my print and then go to file explore to delete/rename/modify this file i the error below.
Currently i have to close my application then i can modify the tif documents.

enter image description here

Answer

In any case, you'll need to wrap your image in a using block like you described in your edit, since Image.FromFile() will keep a lock on the file until the image is disposed.

The ObjectDisposedException you're seeing is coming from the printPreviewDialog, unrelated to loading images. You can either...

(a) use printPreviewDialog1.ShowDialog(this) instead to show a dialog modally (i.e., block input to the parent window while the dialog is open), which won't dispose the dialog after closing it

or, (b) use printPreviewDialog.Show(this) to show the dialog non-modally, like you do now, but add the following callback:

    private void printPreviewDialog1_FormClosing(object sender, FormClosingEventArgs e)
    {
        // Don't close and dispose the form if the user is just dismissing it. Hide instead.
        if (e.CloseReason == CloseReason.UserClosing)
        {
            e.Cancel = true;
            printPreviewDialog1.Hide();
        }
    }
Comments