Click here to Skip to main content
15,885,835 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
With the use of FileSystemWatcher the program should automatically process newly created images from a set directory. When detecting a new image for the first time, this works fine. The second detection however raises the error 'Object is used elsewhere'.
namespace INFOIBV
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new INFOIBV()); //<----- Exception raised
        }
    }
}

Probably something goes wrong in one of the following methods:
public INFOIBV()
{
    InitializeComponent();
    Watcher();
}

private void Watcher()
{
    var fileSystemWatcher = new FileSystemWatcher(@"C:\path\input_images")
    {
        Filter = "*.jpg",
        NotifyFilter = NotifyFilters.FileName,
        EnableRaisingEvents = true
    };

    fileSystemWatcher.Created += OnFileCreated;
}

private void OnFileCreated(object sender, FileSystemEventArgs e)
{
    if (InputImage != null) InputImage.Dispose();
    InputImage = new Bitmap(e.FullPath);
    pictureBox1.Image = (Image)InputImage;

    apply(InputImage);
}

My main question thus is, how can I modify the program such that it can process an influx of images from a specified folder without accessing the same object more than once?

What I have tried:

When placing the work (the entire invocation of the image retrieval, processing - which the apply() function does - and outputting) that is inside OnFileCreated inside a ThreadPool the 'Object is used elsewhere' exception shifted to the apply() method:
private void apply(Bitmap image)
        {
            if (InputImage == null) return;
            if (OutputImage != null) OutputImage.Dispose();
            OutputImage = new Bitmap(InputImage.Size.Width, InputImage.Size.Height);
            Image = new Color[InputImage.Size.Width, InputImage.Size.Height];

            // copy input Bitmap to array            
            for (int x = 0; x < InputImage.Size.Width; x++) //<----- Exception raised
                for (int y = 0; y < InputImage.Size.Height; y++)
                    Image[x, y] = InputImage.GetPixel(x, y);           

I have also tried to execute the entire pipelinege while locked but then the first incoming image gives no reaction of the program, the second goes as wished and the third image yields the same old 'Object is used elsewhere' exception. Initializing the locked Bitmap as a cloned version results in a 'bitmap region already locked' error in the last line of last code snippet:
Image[x, y] = InputImage.GetPixel(x, y); //<----- bitmap region already locked

This thread seemed to be promising towards a solution but I don't understand the underlying mechanism.

Why for example do both making a local copy as in localImage = (Bitmap)InputImage; nor after each run Disposing the InputImage not work?
Any help in understanding this issue would be very much appreciated
Posted
Comments
[no name] 22-Oct-22 19:19pm    
You're dealing with IDisposable classes; I don't see any disposing code "after" the fact; just trying to dispose "before" ... where there is now a race condition.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900