Avatar billede skurggman Nybegynder
04. januar 2006 - 19:16 Der er 9 kommentarer og
1 løsning

Cross threading

Hej

Jeg har en progressbar som tilhører en form klasse, og jeg har en metode som udfører en iteration i samme klasse, men iterationen bliver startet i en ny tråd... derfor kan jeg ikke umiddelbart "performestep" på progressbaren, da den siger at det er en ulovlig cross threading operation...

Hvordan løser jeg dette problem?

/Mvh.
Kim Schurman
Avatar billede arne_v Ekspert
04. januar 2006 - 19:21 #1
det lyder som det #¤#!¤/#"! problem hvor du er nødt til at bruge Invoke
Avatar billede skurggman Nybegynder
04. januar 2006 - 19:23 #2
Kan du uddybe det? :) H

Har aldrig hørt om det problem...
Avatar billede arne_v Ekspert
04. januar 2006 - 19:24 #3
prøv og kig på den her kode:

using System;
using System.Drawing;
using System.IO;
using System.Net;
using System.Windows.Forms;
using System.Threading;

public class MainForm : Form
{
    private ProgressBar bar;
    private Button start;
    private Button abort;
    private Thread t;
    public MainForm()
    {
        bar = new ProgressBar();
        start = new Button();
        abort = new Button();
        SuspendLayout();
        bar.Location = new Point(50, 50);
        bar.Size = new Size(200, 50);
        bar.Name = "Progress Bar";
        start.Location = new Point(50,150);
        start.Size = new Size(200, 50);
        start.Name = "Start Button";
        start.Text = "Start";
        start.Click += new EventHandler(StartClick);
        abort.Location = new Point(50,250);
        abort.Size = new Size(200, 50);
        abort.Name = "Abort Button";
        abort.Text = "Abort";
        abort.Click += new EventHandler(AbortClick);
        ClientSize = new Size(300, 350);
        Controls.Add(bar);
        Controls.Add(start);
        Controls.Add(abort);
        Name = "Main Form";
        Text = "Main Form";
        ResumeLayout(false);
    }
    void Reset(int n)
    {
        bar.Minimum = 0;
        bar.Maximum = n;
        bar.Value = 0;
    }
    void Update(int n)
    {
        bar.Value = n;
    }
    delegate void ResetHandler(int n);
    delegate void UpdateHandler(int n);
    void Copy()
    {
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://www.tmk.com/ftp/vms-freeware/fileserv/unzip.zip");
        HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        int tot = (int)resp.ContentLength;
        if(bar.InvokeRequired)
        {
            bar.Invoke(new ResetHandler(Reset), new object[] { tot });
        }
        else
        {
            Reset(tot);
        }
        Stream f1 = resp.GetResponseStream();
        Stream f2 = new FileStream(@"C:\unzip.zip", FileMode.CreateNew, FileAccess.Write);
        int sofar = 0;
        byte[] b = new byte[1000];
        int n;
        while((n = f1.Read(b, 0, b.Length)) > 0 )
        {
            f2.Write(b, 0, n);
            sofar += n;
            if(bar.InvokeRequired)
            {
                bar.Invoke(new UpdateHandler(Update), new object[] { sofar });
            }
            else
            {
                Update(sofar);
            }
        }
        f2.Close();
        f1.Close();
        resp.Close();
    }
    void StartClick(object sender, EventArgs e)
    {
        t = new Thread(new ThreadStart(Copy));
        t.Start();
    }
    void AbortClick(object sender, EventArgs e)
    {
        t.Abort();         
    }
    [STAThread]
    public static void Main(string[] args)
    {
        Application.Run(new MainForm());
        Application.Exit();
        Environment.Exit(0);
    }
}
Avatar billede arne_v Ekspert
04. januar 2006 - 19:24 #4
den kører en HTTP download i en tråd og opdaterer en ProgressBar

(jeg bruger ikke PerformStep men ...)
Avatar billede skurggman Nybegynder
04. januar 2006 - 19:25 #5
Tak jeg kigger på det :)

Smider du et svar?
Avatar billede arne_v Ekspert
04. januar 2006 - 19:26 #6
gerne

men check lige om det er det som er skyld i dit problem
Avatar billede segato Nybegynder
04. januar 2006 - 20:37 #7
Brug BeginInvoke så starter den selv en tråd.
Avatar billede skurggman Nybegynder
04. januar 2006 - 22:39 #8
Hvordan bruger man begininvoke og delegates, jeg har også nogen metoder som tager argumenter, der gerne skal eksekveres i en tråd for sig selv, hvordan får man parametre med??
Avatar billede segato Nybegynder
04. januar 2006 - 23:45 #9
public delegate void SelectTreeNodeDelegate(int someMessage);
        void m_extractorController_onNavigateNext(int index)
        {
            if (index != -1)
            {
                m_ucNaviagteView.Invoke(new SelectTreeNodeDelegate(m_ucNaviagteView.SelectTreeNode), new object[] { index });               
            }
            }


Du matcher bare en delegate til den function du vil kalde på din kontrol. Det ganske simpelt.
Avatar billede segato Nybegynder
04. januar 2006 - 23:45 #10
Erstat lige Invoke med begininvoke
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester