Projekt „Nový hledač“
Dotazy

Dotazy číslo 3 a 4 jsou zodpovězeny, viz níže.


V současné době mám v podstatě všechny problémy vyřešeny.


Dotaz číslo 1


Staženou stránku potřebuju překódovat do UTF-8 a v tomto kódu ji také uložit.

Informace o původním kódu stránky dostanu z:

1. (HttpWebResponse)http_web_request.GetResponse().CharacterSet;

2. <meta http-equiv="Content-Type" content="text/html; charset=xxx" />

(xxx je příslušný definovaný kód stránky).

Bod číslo 2 má přitom preferenci.

Ovšem může se stát:

- bod číslo 1 i bod číslo 2 jsou prázdné

- bod číslo 1 je špatně, serverch hlásí jiné kódování než má stránka ve skutečnosti, přitom je bod číslo 2 prázdný.

Například na mých serverech na Active24 mám kódování windows-1250 a přitom mi server dává ISO-8859-1.

Má to nějaké řešení, můžu ještě z nějakého jiného zdroje zjistit skutečné kódování příslušné stránky?

 

Dotaz číslo 2

Jaký má význam destruktor, má smysl jej do objektů (tříd) zařazovat?
Jaký má význam IDisposable, má smysl jej do objektů (tříd) zařazovat?
Jaký má význam Dispose, má smysl jej do objektů (tříd) zařazovat?

Dát na konec (deklarace či použití) všech objektů, které dělám pomocí „new“ příkaz Dispose?

Pokud vlákno skončí, jsou tím uvolněny všechny jeho "interní zdroje", tedy vše, co mu nebylo dodáno zvenčí, včetně paměti, kterou to vlákno zabralo?

Tedy, je to obdoba ukončení samostatně běžícího procesu?

Dotaz číslo 3


Ad sdílení proměnných mezi vlákny, tedy mezi dvěma různými (new) instancemi téže třídy (metody).

 

Fronter je řídící program pro Downloadery,

Downloader stahuje jednotlivé stránky.

Downloadery jsou zapsány jako třídy (metody) ve zdrojáku Fronteru.

 

Takhle to vlákno (ta vlákna) ve Fronteru startuju:

 

ThreadStart thread_start=new ThreadStart(Downloader);

gd.thread_=new Thread(gd.thread_start);

gd.thread_.Start();

 

Takhle je ta třída Download, resp. metoda Downloader, naprogramována:

 

class Download

  {

    private class gd

      {

        public static int i;

      }

    public void Downloader()

      {

        gd.i=1;

      }

  }

 

Pokud tu třídu (metodu) nastartuji výše uvedeným způsobem dvakrát či vícekrát,

pak tu proměnnou "i", tedy ve výskytech "gd.i", vlákna sdílejí,

tedy do ní během běhu dosazují různé hodnoty,

testují její hodnoty apod.,

což samozřejmě dělá vzájemně ve vláknech nepořádekl.

 

Potřebuju mít takhle udělaný ty globální deklarace "gd",

protože tam mám stovky proměnných a není možné možný je předávat metodám přes parametry.

Zkouším to nějak takhle:

class Download

  {

    public class GD

      {

        public static int i;

      }

    public void Downloader()

      {

          GD1 gd1=new GD1();

        gd.i=1;

      }

    public void SomeMethod()

      {

        gd.i=1;

      }

  }


Pro ten příkaz „gd.i=1;“ v metodě Downloader to funguje.

Pro ten příkaz „gd.i=1;“ v metodě SomeMethod to nefunguje.
Potřeboval bych konstrukci, která funguje pro všechny metody.

Problém je vyřešen:

 

Uf, podruhé, tak sem dodělal to spouštění Downloaderů ve vláknech Fronteru bez duplikací Downloaderů ve zdrojovém kódu.

Oříšek byl, že v Downloaderu mám hodně metod a stejně jako v dalších programech používám globální proměnné (je to daleko jednodušší než předávání hodnot přes parametry nebo objekty). Ale tyto globální proměnné pro každý Downloader samozřejmě nesmějí sdílet ani Fronter, ani jednotlivá vlákna Downloaderů vzájemně.

Trvalo mi to 24 hodin, jako obvykle skoro v kuse.

Ušel sem 4 slepá uličky, které nefachčily:

- ThreadStatic nefunguje pro pole
- ThreadLocal vyžaduje zvlášní způsob deklarací (a mám dojem, že taky moc nefunguje)

- vytvoření nové instance třídy s globálními parametry Downloaderu ve Fronteru a předávání této instance Downloaderům přes parametr (tohle by možná chodilo, ale už to mám hotový, tak se k temu nebudu vracet)

- vytvoření nové instance třídy s globálními parametry Downloaderu až v Downloaderu

Správné ulice byly tyto:

- vytvoření nové instance třídy s globálními parametry Downloaderu ve Fronteru a předání přes proměnnou Downloaderu
- zkopírování třídy globálních proměnných přímo do Downloaderu a použití .this v programu a metodách Downloaderu

Děkuji konzultantům za rady.

PS1
Teďky můžu pokračovat v optimalizaci paměti a časů.

PS2
Takže si budu moci vyzkoušet, zda mají jet Downloadery jako samostatné procesy, nebo ve vláknech Fronteru a zvolit rychlejší variantu.

 

Dotaz číslo 4


Spouštění vláken

Pokud spustím nějaký program (=proces) z řídícího programu v C# pomocí příkazu Process.Start, pustí se ten program v tom samém vlákně, jako program řídící, nebo se pro něj udělá nové samostatné vlákno?

 

Obecně:

jak se z dávky (Windows .bat, Linux .sh) a z programu (.exe) spouštějí programy(=procesy) tak, aby běžely:

- všechny v jednom vláknu

- každý v samostatném vláknu?

Nebo jinak:
Pokud spouštím programy (=procesy) z jedné dávky (Windows .bat, Linux .sh) paralelně pomocí příkaz START,
spustí se každý program v samostatném vláknu, nebo se všechny ty programy spustí v jednom vláknu (ve vláknu té dávky)?

 

Pokud mám 100 programů Worder, z nichž každý načte uloženou WWW stránku, rozparsuje ji a uloží z ní nějaká data, přičemž každý ten Worder pracuje na disjunktní množině WWW stránek (vzájemně nespolupracují ani se neovlivňují), je výhodnější spustit všechny v jednom vlákně nebo každý ten Worder v samostatném vláknu?

Problém je vyřešen:

Downloadery mohu spouštět jako samostatné procesy i vlákna Fronteru.