Avatar billede ttgeek Nybegynder
18. juni 2007 - 15:36 Der er 4 kommentarer og
1 løsning

Multithreading i .net application

Hej med jer.

Jeg har en applikation, der udfører en masse arbejde. Nu skal applikationen udvides med en service, der henter addressen for et givet telefon nr. Denne funktionalitet skal ske i baggrunden, så applikationen ikke skal vente på resultatet.

Jeg har udviklet nedenforstående kode, men når jeg lader tråden sove, hænger hele applikationen.. Det kunne tyde på at applikationen venter på at tråden bliver færdig alligevel. Hvad gør jeg forkert?

private void StartLookupAddressThread(string PhoneNo)
{
    System.Threading.Thread th = new System.Threading.Thread(
        new System.Threading.ParameterizedThreadStart(LookupAddresss));
    th.SetApartmentState(System.Threading.ApartmentState.MTA);

    th.Start(PhoneNo);
}
public delegate void MyDelegateMethod(object TelePhone);
public void LookupAddresss(object TelePhone)
{
    if (this.InvokeRequired)
    {
        MyDelegateMethod theDelegateMethod = new MyDelegateMethod(this.LookupAddresss);
        this.Invoke(theDelegateMethod, TelePhone);
    }
    else
    {
        try
        {
            // Removes any occurences of +,-,space,< or >
            string phoneNo = System.Text.RegularExpressions.Regex.Replace(
                TelePhone.ToString(), "
  • +|
    • +|[<]+|[>]+|[ ]+", "");

            ER.NavneNumreService.NNService nn = new ER.NavneNumreService.NNService(phoneNo);
            // Locks the address form resource for concurrency
            lock (AddressForm)
            {
                // Any numbers left?
                if (nn.LookupAddress(true))
                {
                    AddressForm.ShowAddress(nn.Address);
                    if (!AddressForm.Visible)
                        AddressForm.Show(this);
                    this.Focus();
                }
                else
                    AddressForm.ShowAddress("");
            }
            System.Threading.Thread.Sleep(10000);
        }
        catch (Exception ex)
        {
            Debug.HandleException(ex);
        }
    }
}

private void buttonFindAddress_Click(object sender, EventArgs e)
{
    StartLookupAddressThread(comboBoxDialNumbers.Text);
}
Avatar billede bennytordrup Nybegynder
19. juni 2007 - 08:24 #1
Det vil den gøre ja, for den del af LookupAddress, du kalder Thread.Sleep i, bliver i praksis udført på GUI-tråden.

Hvorfor kalder du Thread.Sleep?
Avatar billede ttgeek Nybegynder
19. juni 2007 - 16:50 #2
Jeg kalder Thread.Sleep for at teste om jeg har opnået det jeg ville, ved at benytte flere tråde. Det lader det ikke til jeg har opnået.

Jeg vil gerne udføre kaldet nn.LookupAddress(true) i en anden tråd end den der håndtere gui, da kaldet kan tage lang tid.
Avatar billede bennytordrup Nybegynder
20. juni 2007 - 08:11 #3
I det tilfælde er din tilgang forkert, for din implementering gør, at du i praksis får udført den på UI tråd. Du sætter den i gang på en anden tråd, men via test på InvokeRequired og den håndtering får du marshallet den tilbage på UI tråd.

LookupAddress skal være den metode, som startes på anden tråd, og det har du korrekt nok. Men implementationen af skal kun indeholde det reelle opslag (instantiering af nn og kald af metoder på nn).

Dernæst skal du have rutiner til rapportering, og *disse* rutiner skal indeholde logik med test på InvokeRequired og dertil hørende Invoke. Det er faktisk hele ShowAddress, jeg ville pakke i en selvstændig rutine, der håndterer InvokeRequired og Invoke. Desuden ville jeg lave en void EnsureVisible(), som under InvokeRequired og Invoke håndterer testen på Visible og kaldet til Show.
Avatar billede ttgeek Nybegynder
21. juni 2007 - 13:49 #4
Jeg har fulgt dine anvisninger (næsten til punkt og prikke) og dét ser ud til at virke. mange tak.
Jeg har lige et tillægs spørgsmål dog. Er formen AddressForm en delt ressourse? Jeg tror ikke den er det, men vil lige høre eksperten :)

Her er koden som den ser ud nu, efter ændringen:
    #region NavneNumreService Functionality and Event Handlers
    private void StartLookupAddressThread(string PhoneNo)
    {
        System.Threading.Thread th = new System.Threading.Thread(
            new System.Threading.ParameterizedThreadStart(LookupAddress));
        th.SetApartmentState(System.Threading.ApartmentState.STA);

        th.Start(PhoneNo);
    }
    private void LookupAddress(Object TelePhone)
    {
        try
        {
            // Removes any occurences of +,-,space,< or >
            string phoneNo = System.Text.RegularExpressions.Regex.Replace(
                TelePhone.ToString(), "
  • +|
    • +|[<]+|[>]+|[ ]+", "");

            NNService nn = new NNService(phoneNo);

            // Any address found?
            if (nn.LookupAddress(true))
            {
                ShowAddress(nn.Address);
            }
            else
                ShowAddress("");
        }
        catch (Exception ex)
        {
            Debug.HandleException(ex);
        }
    }
    public delegate void MyDelegateMethod(object TelePhone);
    public void ShowAddress(object Address)
    {
        if (this.InvokeRequired)
        {
            MyDelegateMethod theDelegateMethod = new MyDelegateMethod(this.ShowAddress);
            this.Invoke(theDelegateMethod, Address);
        }
        else
        {
            AddressForm.ShowAddress(Address.ToString());
            if (!AddressForm.Visible)
                AddressForm.Show(this);
            this.Focus();
        }
    }

    private void buttonFindAddress_Click(object sender, EventArgs e)
    {
        StartLookupAddressThread(comboBoxDialNumbers.Text);
    }
    #endregion
}
Avatar billede bennytordrup Nybegynder
21. juni 2007 - 14:01 #5
Det kommer an på hvad, du mener med delt ressource. Hvor er den erklæret? Er den erklæret som

  Form AddressForm;

eller

  static Form AddressForm;

static kommer nok nærmest det, du mener med delt ressource.
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