Entwickler-Ecke
Basistechnologien - Clipboard.GetText() ist schon was mysteriöses?
BlackMatrix - Do 22.07.10 23:00
Titel: Clipboard.GetText() ist schon was mysteriöses?
Hi.
C#-Quelltext
1: 2:
| [STAThread] static void Main() |
Ich rufe in der Main eine Methode einer Klasse auf und diese Methode ruft wiederum im Laufe der Abarbeitung wie eine private Methode auf, die folgendes ausführt:
C#-Quelltext
1:
| string str = System.Windows.Forms.Clipboard.GetText(); |
Funktioniert wunderbar. Der Inhalt des Zwischenablage wird in den string geschrieben.
Rufe ich nun jedoch die Methode der Klasse in der Main nicht direkt auf, sondern lasse einen Threadpool das tun, dann wird der Inhalt der Zwischanablage nicht in den string kopiert.
C#-Quelltext
1:
| ThreadPool.QueueUserWorkItem(klasse.aufruf, streamreader.ReadLine()); |
Wo liegt das Problem?
BlackMatrix - Do 22.07.10 23:38
Hmm, kann es sein, dass dies auch nicht das Problem ist?
Ich habe nun den Threadpool entfernt und folgendes dafür geschrieben:
C#-Quelltext
1: 2:
| Thread thread = new Thread(new ParameterizedThreadStart(klasse.aufruf)); Thread.Start(sr.ReadLine()); |
Trotzdem übernimmt er es nicht in den string, obwohl der Inhalt in der Zwischenablage ist.
Vielleicht kann man auch mein Problem grundauf abändern/verbessern, sodass dann das Problem gar nicht mehr entsteht? Besserer Code ist mir immer lieber.
Ich möchte gerne, dass die Abarbeitung parallel abläuft, die einzelnen Abarbeitungen immer das selbe tun, nur mit unterschiedlichen Parametern.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| Klasse klasse = new Klasse(); StreamReader sr = new StreamReader(pfad); while (sr.EndOfStream == false) { Thread thread = new Thread(new ParameterizedThreadStart(klasse.aufruf)); thread.Start(sr.ReadLine()); } |
Wie ist da der Code zu bewerten?
BlackMatrix - Fr 23.07.10 02:46
Unglaublich, das geht sogar :) Vielen Dank.
BlackMatrix - Do 29.07.10 16:29
Ich muss nochmal nachhaken.
Ich starte einen Timer. Wie erreiche ich, dass der Timer auch im STA Mode läuft?
C#-Quelltext
1: 2: 3:
| Timer timer = new Timer(wartezeit); timer.Elapsed += new ElapsedEventHandler(OnTimedEvent); timer.Enabled = true; |
Ralf Jansen - Do 29.07.10 16:50
Du benutzt den System.Timers.Timer? Dann versuch mal vom Timer die SynchronizingObject Property zu setzen. Wenn du den Timer auf einer Form des Hauptthreads verwendest sollt ein
C#-Quelltext
1:
| timer.SynchronizingObject = this; |
reichen. Alternativ auf den Timer im Winforms Namespace umsteigen der kommt ohne Thread aus.
BlackMatrix - Do 29.07.10 17:31
Funktioniert der Windows Forms Timer auch bei einem Windows Dienst? Denn irgendwie startet er nicht.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); timer.Interval = 1000; timer.Tick += new EventHandler(OnTimedEvent); timer.Enabled = true; timer.Start(); }
void OnTimedEvent(object source, EventArgs e) { [...] } |
und wenn ich den System.Timers.Timer verwende mit
timer.SynchronizingObject = this; kommt folgendes mit dem ich nichts anfangen kann:
| Zitat: |
| Klasse kann nicht in System.ComponentModel.ISynchronizeInvoke konvertiert werden kann. |
Ralf Jansen - Do 29.07.10 17:54
Ah. Ein Windows Dienst. Wichtiger Hinweis. Gut das du das gleich erwähnt hast :roll: Da werden beide Ratschläge nicht helfen. ISynchronizeInvoke muss schon von den entsprechenden Klassen implementiert sein, wie etwa bei Winforms Controls damit das mit dem SynchronizingObject funktioniert und der andere Timer braucht eh eine MessagePump die ein Windows Dienst üblicherweise nicht hat.
Vielleicht hilft die das vorgehen aus diesem
Thread [
http://stackoverflow.com/questions/2001667/net-windows-service-needs-to-use-stathread].
Rückfrage - Ich habe Vorstellungsprobleme warum man vom einem Dienst aus auf das Clipboard zuzugreifen muß. Das Clipboard gehört doch zur Usersession und auf den Desktop eines Users zuzugreifen ist eher ungewöhnlich für einen Dienst. Maximal kommt man eh nur ans Clipboard des interaktiven Users.
BlackMatrix - Do 29.07.10 18:05
Tut mir leid, dass ich das nicht hinzugeschrieben habe.
Mein Dienst soll auf Clipboard zugreifen könnnen, weil mir ein externes Programm (FineReader) die Ausgabe nur über sehr, sehr viele Umwege in eine Textdatei bringt. Die (fast) einzigste Möglichkeit ist es den String aus der Zwischenablage zu lesen und das funktioniert auch soweit sehr gut, nur eben nicht in Verbindung mit einem Timer.
Also kann ich sozusagen gleich wieder zu meiner anfänglichen Lösung zurückkehren. Einfach für jedes Objekt einen Thread starten und den STA setzen?
Ralf Jansen - Do 29.07.10 20:10
Vermutlich ja.
Du könntest mal die Clipboard Implementierung aus WPF(System.Windows.Clipboard) anstatt die aus Winforms ausprobieren. Zumindest die Hilfe sagt nicht aus über das Apartment Verhalten. Ist aber wahrscheinlich das die das gleiche Problem haben wird da die Ursache eigentlich unterhalb der Winforms bzw. WPF Schicht liegt.
Im VisualBasic.MyService Namespace gibts auch noch ein ClipboardProxy Implementierung. Wird aber vermutlich ebenfalls von dem Problem betroffen sein.
BlackMatrix - Do 29.07.10 21:52
Habe das WPF Cliboard probiert, jedoch funktioniert das auch nicht.
Irgendwo habe ich gerade gelesen, dass bei einem Windows Dienst der [STAThread] z.B. vor der Main keine Auswirkung hätte, jedoch stimmt das nicht, in der Main funktioniert das Clipboard wunderbar.
Nur dann beim Timer eben nicht mehr.
Ich starte jetzt bei den Timern jeweils in der ElapsedTimeEventMethode einen neuen STAThread. Finde ich ehrlich gesagt sehr unschön, aber wie es so schein, tut es erstmal funktionieren. Ich danke dir.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!