C
campk
hoping anyone might be able to shed some light on the situation i am
seeing...
i am working on developing a custom data ETL app for in-house use.
The three relevant objects in question are...
my form
the database mapping object
the table mapping object
The form invokes the DbMapping.RunMigration() method on a new thread;
from there,
the DbMapping.RunMigration method loops through its collection of
TableMapping objects and invokes their respective "RunETL" methods, in
sequence.. Each TableMapping object has events that it fires during
the process of extraction, transformation, and loading
(the Form object listens for these events and responds appropriately.)
(if it may prove relevant, the extraction/load are performed using a
SqlBulkCopy object with a dataset source)
Given that the events coming from the TableMapping objects are coming
off a different thread, I am using the following logic (general format
for all my event handlers)
private void DbTableMapping_ExtractionStarted(DbTableMapping sender,
TableOperationEventArgs e) {
try {
if (this.InvokeRequired) {
delExtractionStarted del = new
delExtractionStarted(DoExtractionStarted);
this.BeginInvoke(del, new object[] { sender, e });
}
else {
DoExtractionStarted(sender, e);
}
}
catch (InvalidOperationException ex) { Log(ex); }
}
In the actual method, i.e., "DoExtractionStarte()", I manipulate
elements in my [custom] listview to show progress.
When I launch the form and run it, everything works fine, with no
problems. The problems start when i close the form and then open it
right back up [from the another form]... When I open this form, I
create a new instance every time.
Any time I open it, subsequent to the first time, when the event
handlers are called, it goes to heck. "this.InvokeRequired" reports
as "false", even though it should be true; when i debug it, I find
that the form's "this.IsDisposed" property is "true", when i try to
access the Handle, it throws an exception, etc. Everything indicates
that the form has been destroyed, but yet the HandleDestroyed event is
never fired, and the form continues running along like nothing has
happened.
As a side note, I am caching the ListViewItems in a HashTable so that I
can look them up quickly; this is the only reason I can continue to
update the progress; if I try to access the ListView, it reports as
having 0 items, and if I try to do "EnsureVisible" using the .Index
property of the cached ListViewItem, it throws an ArgumentOutOfRange
exception, because the index reports as -1, as though all items have
been removed from the ListView..
However, when the thread finishes, and I break execution to check these
properties again, everything is right back to normal; the form's handle
is there, it's not reporting as disposed, etc. I am at a loss, and am
not sure where the problem may be coming from.
I suspect it may be in the use of threads, although I am not sure how
it would impact this behavior, because I don't even have to run the
threaded routine to see this behavior in subsequent instances; I can
open the form, close the form, run the process, and it still behaves in
this manner.
Very strange behavior given that the form is instantiated as a new
object each and every time, and the initial instance works fine with 0
errors... I hope someone out there can provide some insight on this for
me -
Thanks!
campkd
seeing...
i am working on developing a custom data ETL app for in-house use.
The three relevant objects in question are...
my form
the database mapping object
the table mapping object
The form invokes the DbMapping.RunMigration() method on a new thread;
from there,
the DbMapping.RunMigration method loops through its collection of
TableMapping objects and invokes their respective "RunETL" methods, in
sequence.. Each TableMapping object has events that it fires during
the process of extraction, transformation, and loading
(the Form object listens for these events and responds appropriately.)
(if it may prove relevant, the extraction/load are performed using a
SqlBulkCopy object with a dataset source)
Given that the events coming from the TableMapping objects are coming
off a different thread, I am using the following logic (general format
for all my event handlers)
private void DbTableMapping_ExtractionStarted(DbTableMapping sender,
TableOperationEventArgs e) {
try {
if (this.InvokeRequired) {
delExtractionStarted del = new
delExtractionStarted(DoExtractionStarted);
this.BeginInvoke(del, new object[] { sender, e });
}
else {
DoExtractionStarted(sender, e);
}
}
catch (InvalidOperationException ex) { Log(ex); }
}
In the actual method, i.e., "DoExtractionStarte()", I manipulate
elements in my [custom] listview to show progress.
When I launch the form and run it, everything works fine, with no
problems. The problems start when i close the form and then open it
right back up [from the another form]... When I open this form, I
create a new instance every time.
Any time I open it, subsequent to the first time, when the event
handlers are called, it goes to heck. "this.InvokeRequired" reports
as "false", even though it should be true; when i debug it, I find
that the form's "this.IsDisposed" property is "true", when i try to
access the Handle, it throws an exception, etc. Everything indicates
that the form has been destroyed, but yet the HandleDestroyed event is
never fired, and the form continues running along like nothing has
happened.
As a side note, I am caching the ListViewItems in a HashTable so that I
can look them up quickly; this is the only reason I can continue to
update the progress; if I try to access the ListView, it reports as
having 0 items, and if I try to do "EnsureVisible" using the .Index
property of the cached ListViewItem, it throws an ArgumentOutOfRange
exception, because the index reports as -1, as though all items have
been removed from the ListView..
However, when the thread finishes, and I break execution to check these
properties again, everything is right back to normal; the form's handle
is there, it's not reporting as disposed, etc. I am at a loss, and am
not sure where the problem may be coming from.
I suspect it may be in the use of threads, although I am not sure how
it would impact this behavior, because I don't even have to run the
threaded routine to see this behavior in subsequent instances; I can
open the form, close the form, run the process, and it still behaves in
this manner.
Very strange behavior given that the form is instantiated as a new
object each and every time, and the initial instance works fine with 0
errors... I hope someone out there can provide some insight on this for
me -
Thanks!
campkd