Вопрос

I have a GenericHandler as seen below that only save the posted file from jQuery File Upload Plugin, and then do some process on it, then i want to remove the main file, but can't do that and get this error:
The process cannot access the file E:\\Documents\\Visual Studio\\Projects\\NewPreSchoolPanel\\Project\\files\\site\\main-132148717.jpg because it is being used by another process.
This is my code here:

<%@ WebHandler Language="C#" Class="bannerUploader" %>

using System;
using System.Web.Script.Serialization;
using System.IO;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;

public class bannerUploader : IHttpHandler
{

    GlobalFunctions functions;

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";
        try
        {
            functions = new GlobalFunctions();

            HttpPostedFile postedFile = context.Request.Files["file"];
            string path = null, name = null, extension = null;

            int width = 0;

            if (HttpContext.Current.Request["width"] != null)
                width = Int32.Parse(HttpContext.Current.Request["width"]);

            path = context.Server.MapPath("~/files/site/");

            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);

            name = DateTime.Now.ToString("HH:mm:ss") + DateTime.Now.Millisecond;
            name = name.Replace(":", "");
            extension = Path.GetExtension(postedFile.FileName);
            while (File.Exists(path + name + extension))
                name += "A";

            postedFile.SaveAs(path + "main-" + name + extension);

            // How can i dispose or close postedFile Here??

            var img = Image.FromFile(context.Server.MapPath("~/files/site/main-" + name + extension));
            object[] resizeResult = null;

            if (width > 800)
                width = 800;
            else if (width > 700)
                width = 700;
            else if (width > 600)
                width = 600;
            else if (300 < width && width < 600)
                width = 300;
            else
                width = 150;

            resizeResult = img.Resize(width, 0);
            ((Image)resizeResult[0]).Save(context.Server.MapPath("~/files/site/resized-" + name + extension));
            ((Image)resizeResult[0]).Dispose();

            context.Response.Write(new
            {
                status = "success",
                main = "~/files/site/main-" + name + extension,
                extension = extension,
                resized = context.Request.Url.GetLeftPart(UriPartial.Authority) + context.Request.ApplicationPath + "/files/site/resized-" + name + extension,
                ratio = resizeResult[1]
            });
            context.Response.StatusCode = 200;
        }
        catch (Exception ex)
        {
            context.Response.Write(new { Result = "FAILED", Message = ex.Message });
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }

}
Это было полезно?

Решение

You're not disposing of img, so it remains locked (you're only disposing the resized image). Add the following after you're done processing the image:

img.Dispose();

Другие советы

Since you are uploading a file, the file is used by some processes for some time. Either wait and then delete the file or write a code in your global.asax file which will delete the file after session ends as:

//Code to delete multiple files. It will delete all files created one hour back
    void Session_End(object sender, EventArgs e)
        {
    string[] str = System.IO.Directory.GetFiles("Your file path");
                for (int i = 0; i < str.Length; i++)
                {

                        DateTime dt = System.IO.File.GetCreationTime(str[i]);
                        if (dt < DateTime.Now.AddHours(-1))
                            System.IO.File.Delete(str[i]);

                }
    }

You can change the time as you want or can configure it.

Your Problem is a minimal „lag“ between the underling FileStream.Close() call in postedFile.SaveAs() and the actual remove of the file lock. My bet is on installed anti-virus software that checks and lock´s you’re newly created file. All you have to do is wait for the anti-virus or whatever lock´s the file to finish.

Here is some example code:

int tryCounter = 0;
while (true)
{
    try
    {
        tryCounter++;
        //your code here 
        break;
    }
    catch (IOException) //please check if your code does throw an IOException
    {                   //i am just guessing 
        if (tryCounter >= 10)
        {
            throw;
        }

        Thread.Sleep(10);
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top