Getting System.ArgumentException when invoking a delegate

  • Thread starter Thread starter Nony Buz
  • Start date Start date
N

Nony Buz

My objective is simply: Notify a form when a image file has been
created in a directory. First there is a basic interface for the
callback function:

public interface INewImageNotify
{
void notify_NewImage(string imageName);
}

Then there is the delegate:

delegate void DelegateNewImage(string imageName);

The form implements this interface. Then there is a separate
class that manages the FileSystemWatcher. The form creates one of
these class, the constructor looks like this:

public ImageMonitor(string soureDir, string filter,
ImageSelectorForm form)
{
m_form = form;
m_watcher = new FileSystemWatcher(sourceDir, filter);

m_watcher.NotifyFilter = NotifyFilters.LastAccess |
NotifyFilters.LastWrite | NotifyFilters.FileName |
NotifyFilters.DirectoryName;

m_watcher.Created += new FileSystemEventHandler(this. OnCreate);
m_watcher.EnableRaisingEvents = true;
}

then this class implements OnCreate(...):

private void OnCreate(object source, FileSystemEventArgs e)
{
FileInfo fileInfo = new FileInfo(e.FullPath);
if( String.Compare( fileInfo.Extension, ".jpg") == 0 )
{
notify_NewImage(e.FullPath);
}
}

And the class also implements the INewImageNotify interface:

public void notify_NewImage(string imageName)
{
if ((m_form != null) && (m_form.Visible))
{
try
{
object[] args = new object[1];
args[0] = imageName;

m_form.Invoke( new DelegateNewImage( m_form.notify_NewImage), args);
}
catch( System.ArgumentException e)
{
Debug.WriteLine( e.ToString());
}
}
}

The first time this notify_NewImage() gets called, all is well.
The second time through, the Invoke throws
System.ArgumentException. I don't get it! Why does it work once?
Why isn't it working at all after that? Is there a better
approach?
 
I found the problem, but don't know the fix. The problem is that
FileSystemWatcher is too fast. It is notifying as soon as the
file is created, in my case, before the copy is complete. Thus,
in the form where it is loaded, the load fails. How do I find out
when the file is completely copied?
 
Nony said:
I found the problem, but don't know the fix. The problem is that
FileSystemWatcher is too fast. It is notifying as soon as the
file is created, in my case, before the copy is complete. Thus,
in the form where it is loaded, the load fails. How do I find out
when the file is completely copied?

Put the copying routine in a separate thread(so that it won't freeze the app while waiting),
and in it check for ability to copy file periodically, say, once every second or so...
Put file cpying func in try{}catch{} so it won't fire every time it fails.

Something like this:

void ThreadFunc()
{
bool bOk = false;
while (!bOk)
{
try
{
Fiel.Copy(strFileName, strNewFileName);
bOk = true;
}
catch(IOException)
{Thread.Sleep(1000)); // Not correct - don't remember how to call sleep here, but yo u get the idea
}
}


Or to improve, create a thread class and include a callback/delegate function which will fire when
thread is done.

I'm not a "pro" with threads, so maybe you know better way of dealing with threads here, but the
idea is as above. I remember using it myself in a project a year ago - worked perfect

Hope it helps,
Andrey

My objective is simply: Notify a form when a image file has been
created in a directory. First there is a basic interface for the
callback function:

public interface INewImageNotify
{
void notify_NewImage(string imageName);
}

Then there is the delegate:

delegate void DelegateNewImage(string imageName);

The form implements this interface. Then there is a separate
class that manages the FileSystemWatcher. The form creates one of
these class, the constructor looks like this:

public ImageMonitor(string soureDir, string filter,
ImageSelectorForm form)
{
m_form = form;
m_watcher = new FileSystemWatcher(sourceDir, filter);

m_watcher.NotifyFilter = NotifyFilters.LastAccess |
NotifyFilters.LastWrite | NotifyFilters.FileName |
NotifyFilters.DirectoryName;

m_watcher.Created += new FileSystemEventHandler(this. OnCreate);
m_watcher.EnableRaisingEvents = true;
}

then this class implements OnCreate(...):

private void OnCreate(object source, FileSystemEventArgs e)
{
FileInfo fileInfo = new FileInfo(e.FullPath);
if( String.Compare( fileInfo.Extension, ".jpg") == 0 )
{
notify_NewImage(e.FullPath);
}
}

And the class also implements the INewImageNotify interface:

public void notify_NewImage(string imageName)
{
if ((m_form != null) && (m_form.Visible))
{
try
{
object[] args = new object[1];
args[0] = imageName;

m_form.Invoke( new DelegateNewImage( m_form.notify_NewImage), args);
}
catch( System.ArgumentException e)
{
Debug.WriteLine( e.ToString());
}
}
}

The first time this notify_NewImage() gets called, all is well.
The second time through, the Invoke throws
System.ArgumentException. I don't get it! Why does it work once?
Why isn't it working at all after that? Is there a better
approach?
 
Back
Top