Avatar billede trenskow Nybegynder
27. oktober 2006 - 00:43 Der er 7 kommentarer og
1 løsning

Hjælp til tråde og callback

Hejsa

Jeg har nu bakset med det her et par dage, og kan bare ikke få skidtet til at virke.

Jeg får en fejl
"System.InvalidOperationException was unhandled
  Message="Invoke eller BeginInvoke kan ikke kaldes for et objekt, før der er oprettet en vindues-handle."
  Source="System.Windows.Forms"
  StackTrace:
      ved System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
      ved System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
      ved Photo_organizer.ProgressForm.SetlblNumberProcessed(Int32 i) i C:\Documents and Settings\Rasmus\Dokumenter\Visual Studio 2005\Projects\Photo organizer\Photo organizer\ProgressForm.cs:linje 417
      ved Photo_organizer.FindExif.Run(Object status) i C:\Documents and Settings\Rasmus\Dokumenter\Visual Studio 2005\Projects\Photo organizer\Photo organizer\FindExif.cs:linje 49
      ved System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
      ved System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
      ved System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)


Her kommer koden (fylder en del efterhånden, men har fjernet det uvæsentlige

Jeg får min fejl til sidst i koden i public void SetlblNumberProcessed(int i)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Configuration;
using JSG.PhotoPropertiesLibrary;
using FindAllFilesInFolders;
using System.Threading;


namespace Photo_organizer
{
    public partial class ProgressForm : Form, IProgressCallBack
    {
        private System.Threading.ManualResetEvent initEvent = new System.Threading.ManualResetEvent(false);
        private System.Threading.ManualResetEvent abortEvent = new System.Threading.ManualResetEvent(false);
        private List<FileInfo> pictures;
        private List<string> libraries;
        private const string APPTITLE = "Photo Organizer";
        /// <summary>The error title for this application.</summary>
        private const string APPERRORTITLE = APPTITLE + " Error";
        private List<Photo> picturelist;
        private delegate bool InitializePhotoPropertiesDelegate(string xmlFileName);
        public delegate void SetlblNumberProcessedInvoker(int i);
        public delegate void SetProgressPerformStepInvoker();
        private bool requiresClose = true;
        public ProgressForm()
        {
            InitializeComponent();
            _resultOptions = new JSG.PhotoPropertiesLibrary.ResultOptions();
            //PhotoPropertiesLoad();
            picturelist = new List<Photo>();
           
        }
        public void Run(List<string> libraries)
        {
            PhotoPropertiesLoad();
            //Thread t = new Thread(new ThreadStart(GetEXIF));
            this.libraries = libraries;

SearchForPictures();

GetEXIF();
        }
        #region overrides
        protected override void OnLoad(System.EventArgs e)
        {
            base.OnLoad(e);
            ControlBox = false;
            initEvent.Set();
        }
        #endregion


       

        internal void SearchForPictures()…
        internal void GetEXIF()
        {
            FindExif fe;
            this.lblStep.Text = "Step 2 of 4";
            this.lblStatus.Text = "Getting EXIF data";
            this.lblTextProcessed.Visible = true;
            this.lblNumberProcessed.Visible = true;
            this.Repaint();

            this.progressBar1.Maximum = pictures.Count;
            this.progressBar1.Step = 1;
            int i = 1;
            foreach (FileInfo fi in pictures)
            {
               
                    fe = new FindExif(fi.FullName, _resultOptions, picturelist, _photoProps, i);

                    ProgressForm callback = new ProgressForm();
                    try
                    {
                        System.Threading.ThreadPool.QueueUserWorkItem(
                                                      new System.Threading.WaitCallback(fe.Run),
                                                      callback);
                    }
                    catch (System.Threading.ThreadAbortException)
                    {
                        // We want to exit gracefully here (if we're lucky)
                    }
                    catch (System.Threading.ThreadInterruptedException)
                    {
                        // And here, if we can
                    }
                i++;
            }
        }

       
        internal void SaveToDatabase()…
        public void ShowMessage()…
       
        #region EXIF
        private void PhotoPropertiesLoad()…
        private void InitializePhotoProperties(string initXmlFile)…
        public void InitializePhotoPropertiesCompleted(IAsyncResult call)…
        private void ContinueLoadingEvent()…
        #endregion

        #region IProgressCallBack Members
        public void SetProgressPerformStep()
        {
            Invoke(new SetProgressPerformStepInvoker(DoProgressBar1PerformStep));
        }

        public void SetlblNumberProcessed(int i)
        {
            Invoke(new SetlblNumberProcessedInvoker(DoSetlblNumberProcessed), new object[] { i });
        }
        #endregion
        #region Implementation members invoked on the owner thread
        private void DoSetlblNumberProcessed(int i)
        {
            lblNumberProcessed.Text = i.ToString();
        }
        private void DoProgressBar1PerformStep()
        {
            this.progressBar1.PerformStep();
        }
        #endregion

    }
}
----------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml;
using System.Configuration;
using JSG.PhotoPropertiesLibrary;
using System.Threading;

namespace Photo_organizer
{
    public class FindExif
    {
        private JSG.PhotoPropertiesLibrary.PhotoProperties _photoProps;
        private string fileName;
        private ResultOptions _resultOptions;
        private List<Photo> picturelist;
        private int i;
        public FindExif()
        {
           
        }
        //#region EXIF
        public FindExif(string fileName, ResultOptions _resultOptions, List<Photo> picturelist, PhotoProperties _photoProps, int i)
        {
            this.fileName = fileName;
            this._resultOptions = _resultOptions;
            this.picturelist = picturelist;
            this._photoProps = _photoProps;
            this.i = i;
        }
        public void Run(object status)
        {
            IProgressCallBack callback = status as IProgressCallBack;
            AnalyzeAndReport();

            // make callback to update mainGUI
            callback.SetlblNumberProcessed(i);

        }
        private void AnalyzeAndReport()…
        private bool AnalyzeImageFile(string fileName, List<Photo> picturelist)…
        private void ViewAnalysis(string filename, ResultOptions _resultOptions, List<Photo> picturelist)…
    }
}

------------------------------------------------------------

I den sidste her, er det kaldet her callback.SetlblNumberProcessed(i);

Hvad er det lige jeg gør galt med min callback?
Avatar billede md_craig Nybegynder
27. oktober 2006 - 15:54 #1
på MSDN anviser de at man gør således:

        delegate void SetTextCallback( string text );
        public void ExternalCall( string s )
        {

            if ( this.label1.InvokeRequired )
            {
                SetTextCallback d = new SetTextCallback( Call );
                this.Invoke( d, new object[] { s } );
            }
            else
            {
                this.lable1.Text = s;
            }       
        }

        void Call( string s )
        {
            this.label1.Text = s;
        }
Avatar billede md_craig Nybegynder
27. oktober 2006 - 16:03 #2
Bahh..... Trykkede send ved en fejl...
Nå... men...

Overstående og...

Jeg vil lige sige at jeg sad længe og tænkte "Hvad helvede har han gang i" grundet hvad jeg vil mene er dårlig variabel navngivning...

Den variabel du kalder callback, er relet set din form og ikke noget callback... et callback er en metode pointer og i din kode er det en object pointer...
Dette skabte stor forviring for mig... og syntes jeg lige jeg ville poientere...
Avatar billede md_craig Nybegynder
27. oktober 2006 - 16:05 #3
Derudover så fortæl lige lidt om hvad det er du prøver på... ser også ud til at du laver en ny ProgressForm for hvert billede du finder... (det kommer ikke til at gå super godt hvis der er mange billeder er jeg ret sikker på, med mindre det man prøver på er at få ens CPU i knæ)
Avatar billede trenskow Nybegynder
27. oktober 2006 - 23:08 #4
Hejsa, og tak for kommentarerne. Jeg vil kigge på dem med det samme.

Jeg er ved at lave et lille program, som skal skanne forudvalgte foldere på computeren efter billeder, og derefter så skal den hente EXIF data fra alle billederne. Dem vil jeg så sammenligne til sidst, for at se om jeg har dubletter liggende af mine billeder.

Og det ved jeg at jeg har... igennem flere år har jeg gemt alle vores ditigale billeder forskellige steder. Ved en geninstallation, har zippet dem nogle gange, og lavet backup. Nu har jeg så 4-5 steder, hvor jeg har alle mine billeder liggende flere gange. Derfor vil jeg nu søge alle disse foldere igennem, og så få programmet til at vise mig dubletterne, og lade mig vælge originalen, så de kan gemmes i en mappe, og resten i en anden mappe, så de kan slettes.

Jeg går ud fra det er denne her som du hentyder til, når du siger at jeg laver en ny progressform
ProgressForm callback = new ProgressForm();

Jeg har hentet min inspiration til det med callback fra denne side
http://www.codeproject.com/cs/miscctrl/progressdialog.asp?df=100&forumid=2653 , fra den downloadede source.
Han skriver nemlig i sin kode en IProgressCallback callback; // = ??? hvor man så selv skal skrive resten. Men den har jeg ikke kunne hitte ud af endnu. For jeg kan ikke finde ud af hvad der skal stå...
når jeg laver den med mit interface, hvad skal der så stå efter ligmed?
IProgressCallBack callback = ??
Avatar billede trenskow Nybegynder
27. oktober 2006 - 23:25 #5
Jeg har nu prøvet at ændre det til den kode som du skrev

public delegate void SetlblNumberProcessed(int i);

public void ExternalSetlblNumberProcessed(int i)
        {
            if (this.lblNumberProcessed.InvokeRequired)
            {
                SetlblNumberProcessed s = new SetlblNumberProcessed(DoSetlblNumberProcessed);
                this.Invoke(s, new object[] { i });
            }
            else
            {
                this.lblNumberProcessed.Text = i.ToString();
            }
        }

        private void DoSetlblNumberProcessed(int i)
        {
            lblNumberProcessed.Text = i.ToString();
        }

Men resultatet udebliver.
Når jeg step'er igennem min app, så kan jeg se, at invoke ikke er required på lblNumberProcessed, så den istedet går til min else udsagn.. men der bliver ikke skrevet noget på min form.
Avatar billede trenskow Nybegynder
27. oktober 2006 - 23:26 #6
og kaldet ser sådan her ud i min FindExif klasse

public void Run(object status)
        {
            IProgressCallBack callback = status as IProgressCallBack;
            AnalyzeAndReport();

            // make callback to update mainGUI
            callback.ExternalSetlblNumberProcessed(i);
            callback.ExternalSetProgressPerformStep();

        }
Avatar billede trenskow Nybegynder
28. oktober 2006 - 00:52 #7
Tror måske jeg har fundet fejlen ved hjælp af din kode, og så lidt test på denne IProgressCallBack callback = ??

Den skal åbenbart være IProgressCallBack callback = this;
Hvis du vil smide svar :-)
Avatar billede md_craig Nybegynder
28. oktober 2006 - 15:24 #8
Mja hvorfor heder den IProgressCallBack...

Meningen med den klasse er at danne et base interface for CallBacks på forme der behandler process lange opgaver som... den er derfor ikke selv CallBacket, men den giver nogle værktøjer til ProgressCallBacks som er en af de mere alm. opgaver i rigtig mange applikationer... og så er der jo rart man altid har et interface man kan genbruge...

Så det er et interface for Forms hvor du laver ProgressCallBacks på, og ikke interfacet for et Callback...
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