kostaz8 Δημοσ. 8 Μαρτίου 2016 Δημοσ. 8 Μαρτίου 2016 Έχω μια εφαρμογή chat το UI τρέχει στο main thread και έχω ένα thread που θέλω να γράψει σε ένα textbox του UI αλλα όταν πάω να γράψω στον debugger βλέπω πως άλλαξε το text αλλά στο UI δεν έχει αλλάξει εκτός αν βάλω στην εξωτερική κλάση την showDialog() τοτε εμφανίζει νέο παράθυρο με το κείμενο μέσα στο textbox, ενώ εγώ θέλω να γύνετε αυτόματα. Έχω διαβάσει πολύ πράμα στο stack overflow και στο msdn αλλά δεν μπόρεσα να βγάλω άκρη, διάβασα για delegates, dispatchers και invoke αλλά δεν κατάφερα να λύσω το πρόβλημα μου. εξωτερική κλάση κώδικας που τρέχει σε function του thread Form2 form2 = new Form2(); // I assume you set this somewhere public void UpdateTextBox(String text) { form2.setText("test"); } UI thread main κλάση public delegate void changeTextboxHandler(); public event changeTextboxHandler changed; public Form2() { InitializeComponent(); } public void Form2_Load() { } protected virtual void OnNumChanged() { if(changed != null) { changed(); } else { Console.WriteLine("Event fired!"); } } public void setText(String text) { textBox1.Text = text; }
defacer Δημοσ. 8 Μαρτίου 2016 Δημοσ. 8 Μαρτίου 2016 Όπως διάβασες, αυτό που θέλεις δε γίνεται "απευθείας" και θα χρειαστεί (Begin)Invoke. Δεν μπορείς να βγάλεις άκρη αλλά δε μας δείχνεις και τι δοκίμασες να βοηθήσουμε. Το copy paste είναι το πιο εύκολο πράγμα στον κόσμο και ορίστε, αλλά αν δεν καταλάβεις τι παίζει αύριο πάλι το ίδιο θέμα θα έχεις. public void UpdateTextBox(String text) { if (form2.InvokeRequired) { form2.BeginInvoke(new Action(() => form2.setText("test"))); } else { form2.setText("test"); } } 1
kostaz8 Δημοσ. 8 Μαρτίου 2016 Μέλος Δημοσ. 8 Μαρτίου 2016 Την μέθοδο που ποσταρες την βάζω στην κλάση του ui και την καλώ από άλλο thread που τρέχει σε άλλη κλάση, δημιουργώ ένα instance της φόρμας μου στην εξωτερική κλάση και κάνω την κλήση. Συμβαίνει το ίδιο η αλλαγή στο textbox γίνετε αλλά άμα δεν κάνω showDialog δεν το εμφανίζει και ανοίγει καινούριο form.
defacer Δημοσ. 8 Μαρτίου 2016 Δημοσ. 8 Μαρτίου 2016 Πώς γίνεται να τη βάζεις στην κλάση του UI όταν στο πρώτο μήνυμα λες "εξωτερική κλάση κώδικας που τρέχει σε function του thread"; Προφανώς και γω γι' αυτό επέλεξα εκείνη τη method κι όχι άλλη. Το άλλο που λες για ShowDialog και άνοιγμα καινούριου form απλά δεν το καταλαβαίνω αλλά τελείως γενικά, άμα δεν έχεις μπλοκάρει το UI thread με κάτι άλλο (δηλαδή αν τρέχει κανονικά το message pump και όχι δικός σου κώδικας που αργεί πολύ) δεν παίζει να έχεις τέτοια προβλήματα. Και ξανά, κάτσε να διαβάσεις να καταλάβεις τι παίζεται.
M2000 Δημοσ. 9 Μαρτίου 2016 Δημοσ. 9 Μαρτίου 2016 Μήπως χρειάζεται refresh...τα GUI...το θέλουν καμία φορά.
παπι Δημοσ. 9 Μαρτίου 2016 Δημοσ. 9 Μαρτίου 2016 Που εχεις φτιαξει την φορμα σου; στο δευτερο thread; Η λογικη ειναι πολυ απλη. Το main thread φτιαχνει ενα δευτερο thread στο οποιο θα κανεις πασα το reference της φορμας. Στο δευτερο thread, ολες οι κλεισεις στη φορμα, θα γινονται με BeginInvoke. Αυτο ηταν. Βεβαια στην νεα c# εχεις Task await async που κρυβουν ολη αυτη την μακαροναδα με τα threads πχ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace TestForm { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private async void button1_Click(object sender, EventArgs e) { using (var wc = new WebClient()) { var data = await wc.DownloadDataTaskAsync("http://www.insomnia.gr/uploads/profile/photo-thumb-216584.jpg?_r=1384551814"); this.pictureBox1.Image = Image.FromStream(new MemoryStream(data)); } } } }
defacer Δημοσ. 9 Μαρτίου 2016 Δημοσ. 9 Μαρτίου 2016 Μήπως χρειάζεται refresh...τα GUI...το θέλουν καμία φορά. Άμα δεν πιάσει αυτό να κάνει και κανα reboot μετά καλού κακού; 2
M2000 Δημοσ. 9 Μαρτίου 2016 Δημοσ. 9 Μαρτίου 2016 έχω ένα thread που θέλω να γράψει σε ένα textbox του UI αλλα όταν πάω να γράψω στον debugger βλέπω πως άλλαξε το text αλλά στο UI δεν έχει αλλάξει εκτός αν βάλω στην εξωτερική κλάση την showDialog() τοτε εμφανίζει νέο παράθυρο με το κείμενο μέσα στο textbox, Κοίτα βάσει αυτού κάπου έγραψε αυτό που ήθελε. Γιατί δεν εμφανίζεται; Είναι γραμμένο σε νέο αντικείμενο; Είναι γραμμένο εκεί που πρέπει και δεν έχει κάνει ShowDialog; Ύστερα δείχνει ένα UpdateText και ένα event OnNumChanged????
defacer Δημοσ. 9 Μαρτίου 2016 Δημοσ. 9 Μαρτίου 2016 Κρίνοντας από την (τεχνικά ελλιπέστατη) περιγραφή, πιθανότατα γιατί με κάτι απ' όλα αυτά που κάνει κρατάει απασχολημένο το UI thread αντί να το αφήσει να τρέξει message loop όπως είναι το πεπρωμένο του. Αλλά αυτό δεν έχει καμία σημασία. What I'm saying is, η γνωστή σου συνήθεια. Μπορεί να μην έχεις ιδέα τι γίνεται αλλά κάτι θα βρεις να προτείνεις. Κόψτην, κάνει κακό και σε σένα που δε θα μάθεις να προσεγγίζεις το θέμα μεθοδικά και σε όσους αποφασίσουν να ακολουθήσουν τις προτροπές σου. 1
Portmaster Δημοσ. 10 Μαρτίου 2016 Δημοσ. 10 Μαρτίου 2016 Decouple the fuck namespace WindowsFormsApplication1 { using System; using System.Threading; using System.Windows.Forms; using System.Threading.Tasks; public partial class Form1 : Form { private Worker worker_ = new Worker(); public Form1() { InitializeComponent(); } private async void button1_Click(object sender, EventArgs e) { try { await worker_.DoWorkAsync( new Progress<string>(_ => label1.Text = _)); } catch (OperationCanceledException) { label1.Text = "Work cancelled"; } } private void button2_Click(object sender, EventArgs e) { worker_.CancelWork(); } } internal class Worker { private CancellationTokenSource cts_; public Task DoWorkAsync(IProgress<string> pg) { if (pg == null) { throw new ArgumentNullException(nameof(pg)); } if (cts_ != null) { return Task.FromResult(0); } cts_ = new CancellationTokenSource(); return Task.Run(async () => { for (; { cts_.Token.ThrowIfCancellationRequested(); // work work work work work work pg.Report(Environment.WorkingSet.ToString()); await Task.Delay(500, cts_.Token); } }); } public void CancelWork() { cts_?.Cancel(); cts_?.Dispose(); cts_ = null; } } } 1
M2000 Δημοσ. 10 Μαρτίου 2016 Δημοσ. 10 Μαρτίου 2016 Defacer, Μια ιδέα σκέφτηκα, μπορεί να είναι λάθος. Δεν επιτρέπονται τα λάθη; Στο θέμα τώρα. Θέλει να κατεβάσει μια εικόνα και όσο το κάνει η φόρμα είναι απασχολημένη, και μάλλον δεν έχει φορτώσει το text box. Θα μπορούσε να ξεκίνησει το κατέβασμα αφού είχε φορτώσει όλα τα στοιχεία και την εικόνα που θέλει την φορτώνει μετά, ενώ βάζει κάτι πρόχειρο στη θέση της.
Portmaster Δημοσ. 10 Μαρτίου 2016 Δημοσ. 10 Μαρτίου 2016 @M2000 Έδωσε ο παπι sample με async function, δεν είμαστε στις σπηλιές ούτε αυτά τα πράγματα πρέπει να γίνονται στο UI thread.
defacer Δημοσ. 10 Μαρτίου 2016 Δημοσ. 10 Μαρτίου 2016 Defacer, Μια ιδέα σκέφτηκα, μπορεί να είναι λάθος. Δεν επιτρέπονται τα λάθη; Εσύ λες "σκέφτηκα". Εγώ θα το έλεγα "δεν κατάλαβα ούτε το context ούτε το πρόβλημα αλλά ορίστε τι πιστεύω". We've been there before. Το να κάνεις λάθος διάγνωση όντας γιατρός είναι λάθος. Το να κάνεις διάγνωση ενώ δεν είσαι γιατρός δεν ξέρω πως θες να το πεις, αλλά μάλλον δεν είναι "λάθος".
M2000 Δημοσ. 10 Μαρτίου 2016 Δημοσ. 10 Μαρτίου 2016 Δεν αντιλαμβάνομαι το μάθημα! Αυτή την εποχή φτιάχνω το GUI της Μ2000, και δεν ξέρω ποιος άλλος εδώ έχει φτιάξει δικά του windows....Όταν φτιάχνεις κάτι τέτοιο καταλαβαίνεις πέρα από τα βασικά. Δες τελευταίο παράδειγμα στο Blog μου, κώδικας που δεν γίνεται compile, και όμως φτιάχνει δυναμικά παράθυρα. Π.χ όταν ένα στοιχείο περάσει πίσω μια μεταβλητή έστω για να δει κανείς τι θα γραφτεί σε ένα Textbox και να αλλαχτεί πριν αυτό το εμφανίσει (δηλαδή πληκτρολογούμε και η αλλαγή δίνεται για έλεγχο), τότε το μήνυμα πρέπει να πάει άμεσα για διεκπεραίωση. Όμως σε άλλες περιπτώσεις που δεν έχουμε απαίτηση για άμεση επιστροφή τιμής (δεν περνάει By reference) θέλουμε να πάει σε ένα σωρό. σε κάτι όπου θα το πάρει με τη σειρά του κάποιο νήμα, κάτι που δουλεύει ασύγχρονα. Αυτά λοιπόν εσύ μπορεί να τα έχεις χρησιμοποιήσει..αλλά δεν τα έχεις φτιάξει! Οπότε μην μου την λες ως ο ειδικός. Νομίζεις ότι κάνω χαζές ερωτήσεις; Κάνεις λάθος. Κάνω τέτοιες που δεν τις σκέφτεσαι καν. Ο καθένας έχει το τρόπο που σκέφτεται και ό,τι δεν μας φαίνεται οικείο, δυστυχώς κάποιοι το εκμεταλλεύονται για να σπάνε τη πλάκα τους. Τι ήταν τόσο σημαντικό για να με "βάλεις" στη θέση μου; Τίποτα! Απλά δεν καταλαβαίνεις ότι έχεις μια Grootϊαση...όταν δεν μπορείς με ευκολία να προσπεράσεις ότι δεν σου αρέσει! Αν ήμασταν όλοι έτσι θα είχαμε σκοτωθεί για ψύλλου πήδημα!
defacer Δημοσ. 10 Μαρτίου 2016 Δημοσ. 10 Μαρτίου 2016 Ας πούμε ότι ήταν λάθος μου να νομίζω ότι θα έκανε κάποια διαφορά να το πω άλλη μια φορά. Έχεις φτιάξει δικά σου windows και καταλαβαίνεις πέρα από τα βασικά, sure. 1
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα