Avatar billede jackass- Nybegynder
03. oktober 2012 - 11:15 Der er 7 kommentarer

Multi threading

Hej,

Jeg er ved at lave en applikation som skal kalde X antal hosts og returnere nogle værdier som så vises i en DataGridView.

I kolonne index 0 af datagridview'en indtaster man ip/hostname for den/de hosts man vil query. Den del fungerer egentlig fint og jeg modtager værdier, får opdateret de andre kolonner på hver række med værdierne osv.

Men!.. Formen "stener" jo imens programmet kører, hvorfor jeg overvejede at smide "DoStuff()" i en backgroundworker. Men så vil de jo også kun køre 1 ad gangen og vente på hinanden i den samme worker.

Toppen ville vel være dynamisk at starte en tråd pr. row i DataGridView uanset hvor mange der er (eller måske med max-threads) som repræsenterer DoStuff() for hver hosts samtidig. Men dét har jeg ingen idé om hvordan gøres, har forsøgt at Google det, men fattede hat..

Nogen der kan hjælpe godt på vej?
Avatar billede kalp Novice
03. oktober 2012 - 11:20 #1
Du kan benytte en ThreadPool og du er ellers inde på det rigtige med "DoStuff".

Du kan tjekke på InvokeRequired på din form og er den true, kan du kalde Invoke mener jeg den bare hedder.
Avatar billede kalp Novice
03. oktober 2012 - 11:21 #2
Godt eksempel her:
http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx
Avatar billede jackass- Nybegynder
03. oktober 2012 - 12:44 #3
Jeg er lidt blank på det.. Du får lige lidt kode så du kan se hvad jeg gør.

Eksempel for pingtider, pinger jeg hvert sekund med en timer:

public int DoPing(string host)
{
    int result;

    if (!IsIPv4(host))
        result = -1;

    Ping pingSender = new Ping();
    PingOptions options = new PingOptions();
    options.DontFragment = true;

    // Create a buffer of 32 bytes of data to be transmitted.
    string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    byte[] buffer = Encoding.ASCII.GetBytes(data);
    int timeout = 5000;
    PingReply reply = pingSender.Send(host, timeout, buffer, options);
    if (reply.Status == IPStatus.Success)
    {
        result = Convert.ToInt32(reply.RoundtripTime);
    }
    else
    {
        result = -1;
    }

    return result;
}

public void ShowResult(string host, int ms)
{
    for (int i = 0; i < dgview.RowCount; i++)
    {
        if (dgview[0, i].Value != null && dgview[0, i].Value.ToString() == host)
        {
            dgview[1, i].Value = ms + " ms";
            if (ms < 0)
                dgview.Rows[i].DefaultCellStyle.BackColor = Color.Red;
            else
                dgview.Rows[i].DefaultCellStyle.BackColor = Color.White;
        }
    }
}

public void GoPing()
{
    int latency = 0;
    for (int i = 0; i < dgview.RowCount; i++)
    {
        if (dgview[0, i].Value != null)
        {
            latency = DoPing(dgview[0, i].Value.ToString());
            ShowResult(dgview[0, i].Value.ToString(), latency);
        }
    }
}

private void timerPing_Tick(object sender, EventArgs e)
{
    GoPing();
}

..Hvilket virker. Det er vel egentlig enten GoPing() der skal fyres af i seperate tråde pr. host for ikke at "stene" GUI'en?

Jeg ved ikke lige hvordan jeg skal "pakke det ind" i noget der virker.. har forsøgt med dit eksempel :-/
Avatar billede Nereos Nybegynder
03. oktober 2012 - 13:03 #4
Jeg bruger denne til at opdatere min form.
Bogen er super god og gratis.
http://www.albahari.com/threading/part2.aspx#_Rich_Client_Applications
Avatar billede kalp Novice
03. oktober 2012 - 14:26 #5
Du har brugt maks. en time på at forsøge dig frem:) giv det lige en skalde til så lære du mere:)
Avatar billede lclemens Nybegynder
03. oktober 2012 - 16:57 #6
Har du overvejet SendAsync?
Avatar billede Syska Mester
03. oktober 2012 - 18:50 #7
eller .NET 4.5 og async & await ?
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

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