FileSystemWatcher und Thread-Safe Calls to Windows Forms
-
hallo allerseits.
ich schreibe gerade ein programm zum verschieben/überwachen/etc. von files, und zum überwachen habe ich den FileSystemWatcher gewählt. es sah auf den ersten blick ziemlich einfach und straight-forward aus, jedoch trat folgendes szenario auf:
FSW.Changed += new FileSystemEventHandler(OnChanged); // aus dem msdn tut
.
.
.
private void OnChanged(object source, FileSystemEventArgs e)
{
CheckedListBox.Items.Clear(); // und hier tritt dann das problem auf, er meint "der zugriff auf das steuerelement CheckedListBox erfolgte von einem anderen thread als den für den es erstellt wurde".darauf hin las ich mir das "How to: Make Thread-Safe Calls to Windows Forms Controls " tutorial durch, das von der hilfestellung empfolen wurde.
und da ich bisher multithreading nur in java gemacht habe, und mich daher nicht wirklich auskannte, las ich mir auch das "Threading Tutorial" durch. und wie das alles verstanden hatte belief sich der unterschied lediglich darin das einmal die set-methode verwendet wurde, und das andere in das attribut direkt geschrieben wurde. was mich bei all dem jedoch verwirrt ist das ich ja auf garkeine attribute zugreifen will, sondern methoden!
ausserdem gibt es da noch die methode die die id der threads vergleicht:
private void SetText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}das bringt mich aber, wie oben bereits erwähnt, auch nicht weiter. also schaute ich mir noch den BackgroundWorker an, bzw. las mir das msdn und dotnetperls.com tutorial dazu durch. da werden aber auch nur attribute zugewiesen? und das noch asynchron, das will ich ja garnicht!
ich habe in c# nie wirklich viel programmiert, und das themengebiet ist ganz neu, also es kann durchaus sein das ich mich wie ein noob anhöre bzw. noob-fehler mache und das die lösung eigentlich deppeneinfach ist (wahrscheinlich), aber ich habe alles (mir bekannte) ausprobiert und komme einfache nicht weiter.
dabei ist die frage doch ganz einfach: wie schaffe ich es in einer methode eines FSW-events eine methode eines windows-forms auszuführen? und es ist nicht nur eine funktion ohne parameter, sondern auch mit zuweisungen und schleifen etc.
danke im voraus,
mfg
-
-
genau das verlangt nämlich das ich in der thread-klasse was ändere, die thread-klasse ist aber nicht meine sondern der FileSystemWatcher!
-
NNNNN_ schrieb:
genau das verlangt nämlich das ich in der thread-klasse was ändere, die thread-klasse ist aber nicht meine sondern der FileSystemWatcher!
Nein, das verlangt es nicht. Einfach vor
CheckedListBox.Items.Clear();
invoken
-
sfsfs schrieb:
NNNNN_ schrieb:
genau das verlangt nämlich das ich in der thread-klasse was ändere, die thread-klasse ist aber nicht meine sondern der FileSystemWatcher!
Nein, das verlangt es nicht. Einfach vor
CheckedListBox.Items.Clear();
invokendanke vielmals, die schwierigsten lösungen sind immer die einfachsten
noch ein anliegen, ich habe das so definiert:
public delegate void AddListItem();
public AddListItem myDelegate;
private CheckedListBox myListbox;myListbox müsste ein System.Delegate sein oder? dh. wenn ich CheckedListbox1.Invoke(myListbox.Items.Clear())mache, müsste es funktionieren?
das problem das ich jetzt noch habe ist das er mir sagt die methode hätte "invalid arguments"
er meint als argument für CheckedListBox.Invoke(System.Delegate), und egal ob myListbox/myListbox.Items.Clear(), er erkennt es nicht als system.delegate an. und egal welchen overload ich nehme, auch den mit (System.Delegate, object), er hat immer das selbe problem.
danke im voraus
-
public delegate void AddListItemDelegate(); private void OnChanged(object source, FileSystemEventArgs e) { if (InvokeRequired) Invoke(new AddListItemDelegate(AddListItem)); else AddListItem(); } void AddListItem() { myListbox.Items.Clear(); }
oder auch
private void OnChanged(object source, FileSystemEventArgs e) { Invoke(new MethodInvoker(delegate() { myListbox.Items.Clear(); })); }