Új hozzászólás Aktív témák

  • Alexios

    veterán

    válasz joysefke #9300 üzenetére

    Gondolom az a probléma, hogy ez(legalábbis a leírása alapján) x86 vagy x64. Viszont netcore alatt a Microsoft.Data.Sqlite csomagnak is mennie kéne, és azzal szerintem lehet használni ef core-t arm-on is.

    [ Szerkesztve ]

  • joysefke

    veterán

    LOGOUT blog

    válasz Keem1 #9299 üzenetére

    A Task-on már én is agyaltam, de amikor próbálkoztam, valahogy nem jött össze.

    Tessék, ez így működik, gyakorlatilag semmit sem változtattam azon amit bemásoltál. (net framework 4.7.2 + ASP net core 2.1)

    A Console.Readkey(). tartja életben a main thredet, az pedig közvetve a webservice-t. élesben nyilván a console.Readkey helyett valami olyan szerver metódusod lesz, ami sosem ér véget, ezáltal a backgroundban futó futó webservice is életben marad.

    szerk (ne az IIS profillal futtasd)

        public class Program
        {
            static Task _webService;
            public static async Task Main(string[] args)
            {
                Debug.WriteLine("WebGUI Teszt");
                _webService = StartWebGui();
                Console.ReadKey();
            }

            static async Task StartWebGui()
            {
                var hostBuilder = new WebHostBuilder()
                        .UseKestrel()
                        .UseStartup<Startup>()
                        .UseUrls("http://localhost:808/")
                        .Build();
                await hostBuilder.RunAsync();
            }
        }

    [ Szerkesztve ]

  • Keem1

    addikt

    válasz joysefke #9302 üzenetére

    Köszönöm. ezt kipróbálom :)

    "élesben nyilván a console.Readkey helyett valami olyan szerver metódusod lesz, ami sosem ér véget, ezáltal a backgroundban futó futó webservice is életben marad"

    Igen, ezt nagyon jól látod, a solution-ön belül két projectem van, a service, meg egy CLI verzió, próbálom mindkettőt életben tartani, mindkettőt tovább vinni. A CLI alapvetően teszteléshez, debuggoláshoz kell, amit bemásoltam, az onnan való, a service másképp működik.

    Sematikusan:
    ---- Service (project)
    ---------- servicemethods.cs
    ---------- program.cs
    ---- CLI (project)
    ---------- program.cs (<--- servicemethods.cs)

    Itt válnak ketté :)
    Windows alatt a service-t lehet CLI-ként is futtatni, sajnos Linux alatt nem.
    Ha Linux alatt futtatom, ezt kapom: Use mono-service to start service processes

    Ezért fordítok egy második exe-t is, ami gyakorlatilag a paraméterek alapján hívogatja a fő class motyóit. A két program.cs pedig ezeket használja. Az egyik serviceként a másik pedig programként.

    #region Service class
    public class Service : ServiceBase
    {
    public Service()
    {
    ServiceName = Program.ServiceName;
    }
    protected override void OnStart(string[] args)
    {
    Program.OnStart(args);
    }
    protected override void OnStop()
    {
    Program.OnStop();
    }
    }
    #endregion
    #region Main method, application's entry point
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main(string[] args)
    {
    AppInfo.UseLocalDatabaseFolder = true;
    if (System.Environment.UserInteractive)
    {
    ics.logger.Info("Run as application");
    bool showMenu = true;
    while (showMenu)
    {
    showMenu = ConsoleApp.MainMenu();
    }
    }
    else
    {
    ics.logger.Info("Run as service");
    using (var service = new Service())
    {
    ServiceBase.Run(service);
    }
    }
    }
    #endregion

  • Keem1

    addikt

    válasz Alexios #9301 üzenetére

    Köszönöm a tanácsot, de úgy néz ki, ez is elfailel, bár ez más miatt. :F

    Már akkor elkezdtem ijedezni, mikor még Windows alatt is belebotlott a bicskája a connection stringben átadott "version" paraméterben, aminek eddig sem PHP, sem .NET 4.5, sem Java alatt nem volt baja :DDD

    Ez az én kis teszt kódom SQLite teszteléshez:
    using (SqliteConnection conn = new SqliteConnection($@"Data Source=F:\chinook.db;Version=3"))
    {
            conn.Open();
            using (SqliteCommand cmd = new SqliteCommand("SELECT `name` FROM sqlite_master WHERE type='table';", conn))
            {
                    SqliteDataReader reader = cmd.ExecuteReader();
                    while (reader.Read())
                    {
                            System.Console.WriteLine(reader.GetString(0));
                    }
            }
    }

    És Linux alatt ezt kaptam:
    Unhandled exception. Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 14: 'unable to open database file'.
    at Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
    at Microsoft.Data.Sqlite.SqliteConnection.Open()
    at Program.Main(String[] args) in ...\Program.cs:line 24

    [ Szerkesztve ]

  • martonx

    veterán

    válasz Keem1 #9299 üzenetére

    Ne mondd már: https://www.nuget.org/packages/Microsoft.Data.Sqlite.Core/3.1.8
    Talán 2-3 évvel ezelőtt ez igaz is lehetett, manapság ami nincs .Net Core-hoz, azzal nem is érdemes foglalkozni.

    Én kérek elnézést!

  • martonx

    veterán

    válasz Keem1 #9304 üzenetére

    Gyors Guglizás után a version keyword nem támogatott Microsoft.Data.Sqlite.Core alatt függetlenül az operációs rendszertől, más kérdés, hogy Linux alatt szerintem eleve helytelen útvonal az F:\chinook.db
    Helyette Mode=ReadOnly kell a connectionstringbe?

    https://entityframeworkcore.com/knowledge-base/53662829/-net-core-ef6-fehler-mit-sqlite-verbindungszeichenfolge

    Én kérek elnézést!

  • Keem1

    addikt

    válasz martonx #9306 üzenetére

    Nem, Linuxon nem ezt a path-t használtam :)
    Viszont megvan a hiba, nem a Microsoft.Data.Sqlite.Core kell, hanem a Microsoft.Data.Sqlite. Úgy műxik.
    Vannak névkonvencióbeli eltérések a hivatalos verzió és a Microsoft sajátja között, azt már észrevettem. Na de ez a hülyeség, hogy nem mondhatom meg, hogy a DB-m milyen verziójú, ez nonszensz :D

    De úgy tűnik, ezzel tényleg működik ARM alatt.

    No offense, de ha már itt tartunk. Mi az a fő indoka annak, hogy a(z elvileg még maintained) .Net xxx használata eretnekségnek minősül, és ami nincs Core alatt, az felejtős? Tehát mi az az ok, ami miatt a Core mindenképp használandó, más meg kerülendő?
    Én úgy tudtam, az adott programnyelv, környezet csak egy eszköz, semmiképp sem határozza meg a végtermék minőségét. Akár lyukkártyával is megoldhatnám az adott feladatot - más kérdés, hogy meg tudom-e :DDD

    Igen, tudom, a Core eleve opensource-nak, végre platformfüggetlennek készült (más kérdés, hogy eredetileg a .Net is, a Java babérjaira akart törni a 2000-es évek elején), de miért gáz jelenleg .Net-et használni helyette, ha egyébként tökéletesen működik és fejlesztik is?

    [ Szerkesztve ]

  • Alexios

    veterán

    válasz Keem1 #9307 üzenetére

    A .NET fw 4.8-al véget ért, security patchek érkeznek hozzá egy darabig, és kész. Idén jön a .NET 5, az már a core-ra épül, ez a jövő
    Inkább pont fordítva, mi értelme .net fw-ben egy új projektet kezdeni?(főleg 4.5-ben)

    Ráadásul ha linuxon is akarsz .net-et futtatni, eleve nem látom értelmét mással kezdeni, mint az ott natívan támogatott .net core-al

    [ Szerkesztve ]

  • Keem1

    addikt

    válasz Alexios #9308 üzenetére

    Sajnos igazad van :(
    Azt hittem, párhuzamos lesz a kettő, de itt is mást írnak.

    All future investment in .NET will be in .NET Core,” says Microsoft. “.NET Framework 4.8 will be the last major version of .NET Framework.”

    [ Szerkesztve ]

  • joysefke

    veterán

    LOGOUT blog

    válasz Keem1 #9307 üzenetére

    Mi az a fő indoka annak, hogy a(z elvileg még maintained) .Net xxx használata eretnekségnek minősül, és ami nincs Core alatt, az felejtős? Tehát mi az az ok, ami miatt a Core mindenképp használandó, más meg kerülendő?

    Én inkább úgy fogalmaznék, hogy ha valami 3rd party packaget használsz, akkor ha az nincsen .Net Standard-re (lehetőleg max 2.0-ig) akkor az felejtős. Ha van, akkor az jó, mert egy esetleges net framework => net core át-targetelésnek nem fog útjában állni.

    Én semmilyen körülmények között nem használnék olyan 3rd party libet ahol nem látom azt, hogy az arra épülő kódomat át tudom változtatás nélkül emelni akkor is ha futtatókörnyezetet váltok alatta. (lépek frameworkről 4.X-ről Core-ra)

    Ezzel párhuzamosan ha kódot írok próbálom úgy szervezni, hogy közvetlenül framework 4.x-et targetelő projekt(ekbe) minél kevesebb kerüljön és inkább átcsoportosítom olyan projektekbe amelyek netstandard2.0-át targetelnek.

  • martonx

    veterán

    válasz Keem1 #9307 üzenetére

    Látom a többiek időközben megválaszolták a jövő vs. miért ne ragadjunk a múltban, hiszen kényelmes kérdésedet.

    Én kérek elnézést!

  • Keem1

    addikt

    Ok meggyőztetek. Viszont elakadtam, még egy egyszerű tutorial se megy. Windowson oké, Linuxon nem. Mutatom, légyszi segítsetek. :R

    Úgy néz ki, hogy a kis projektem minden egyéb eleme megy Linuxon is, csak a service nem működik. Amúgy tök jó ötlet volt megszabadulni 41 warningtól (unused variable) meg kikukáztam pár, már sehol nem használt metódust is :DDD
    Valahogy ezt a nyamvadt service-t kéne megszülni. Az átoperálás után Windowson az eredeti service .Net Core 3.1-en is megy, és megy az alábbi példa is. Linuxon egyik se.
    Ja, és console appként Linuxon is kiválóan megy, az SQLite is :C
    Csak a service nem... :U

    [link]

    Eredmény Linuxon ( .Net Core 3.1)
    Unhandled exception. System.PlatformNotSupportedException: ServiceController enables manipulating and accessing Windows services and it is not applicable for other operating systems.
    at System.ServiceProcess.ServiceBase..ctor()
    at Testing.LoggingService..ctor()
    at Testing.Program.Main(String[] args) in E:\..\Program.cs:line 39
    Félbeszakítva

    [ Szerkesztve ]

  • Alexios

    veterán

    válasz Keem1 #9312 üzenetére

    Hát, elég egyértelmű az exception :D
    .NET Core 3-al bekerültek olyan api-k is, amik nem platformfüggetlenek. Pl. WPF kódot lehet .NET Core 3-al írni, de ettől még nem fogod tudni linuxon futtatni, ha tippelnem kéne akkor a System.ServiceProcess is ilyen

    [link]
    Szerintem ezt a linket nézd meg, itt jó eséllyel találsz megoldást

  • Keem1

    addikt

    válasz Alexios #9313 üzenetére

    Hát ez remek.. :((
    Jó, akkor ezt egyelőre jegelem, nincs kedvem vacakolni egy olyan funkcióval, ami 4.5 alatt pár sor, .NET Core alatt meg egy csomó macera.
    Majd ha lesz tengernyi időm, akkor szenvedek még vele.

    Köszi azért...

  • joysefke

    veterán

    LOGOUT blog

    válasz Keem1 #9314 üzenetére

    Net api analyzer. Keress rá, rakd fel a VSre és futtasd le mindenféle net standard és net core targetekre, compatibility pack opcióval és anélkül.

    Egyébként mit csináltál? Átraktad a target frameworkot 4.5 ről netcore 3.1 re és most futási időben kapsz hibát? Hogyan futtattad ezt eddig linuxon?

    Amikor átállítottad a target frameworkot, akkor kellett compatibilitás csomagot feltenni?

    [ Szerkesztve ]

  • Keem1

    addikt

    válasz joysefke #9316 üzenetére

    Nem, dehogyis, nyitottam a solution-ön belül egy teljesen új .Net Core 3.1-es projectet, a már létező .Net 4.5-ös console és az ugyancsak 4.5-ös service mellé.

    A service pojecten belül még van 4 db class-em, amik a tényleges munkát végzik, úgy vannak megírva, hogy ne függjenek az adott projecttől (példa: Ac, Bc, Cc, Dc, ezek a class-ek más-más feladatot csinálnak). A service is és a console is ugyanezeket használja.
    A console pl. nem tartalmaz mást, mint 4 db szöveges menüpontot, az 1, 2, 3 és 4 gomb lenyomására voltaképp a fenti class-ek [Ac|Bc|Cc|Dc].Run() nevű metódusát hívják meg és végrehajtják.
    A service is voltaképp ugyanezt csinálja, csak időzítetten, mint egy crontab, megadott időben az Ac.Run(), Bc.Run(), stb hívogatódik, de emellett persze mást is: compactolja az SQLite-ot, futtatja a mini webservert, backupolja a MySQL és az SQLite db-ket.

    Az eredeti elképzelés az volt, hogy a kettő egyben lenne (service-ként, amit a --console argumentummal lehet "menüsíteni"), Windows alatt simán működik is amúgy, alapvetően a --console arggal simán bedobja a console menüt, ketté is van választva a Main() (if (--console) RunConsole(); else RunService();), ez Windows alatt csodásan működik, de a Linux közli, hogy service programot csak service-ként lehet futtatni. Végül a Linux miatt készült egy pár soros Main()-ből álló console verzió is, aminek a tartalma a megírás óta nem változott (ahogy említettem, a menüt futtatja), de igazából a service Main()-je sem... hisz minden abban a 4 db class-ben módosul/frissül.

    Tehát, összegezve... van egy 4 db classből álló feladatcsomagom, amik a Raspberry Pi-n különböző feladatokat hajtanak végre. Emellett van egy console app, ami mauálisan ezeket a feladatokat futtatja, Win/Linux egyaránt. Van egy service-m, ami szintén ezeket futtatgatja, de időzítve, plusz a webes elérést biztosító webserver, plusz pár backup és hasonlók, minden olyasmi, amit egy állandóan a háttérben mozgó service kell hogy futtasson.

    [ Szerkesztve ]

  • kiskornel

    addikt

    Sziasztok!
    Adott egy függvényem, aminek az első bemenő paramétere int, viszont a 2. már lehet string, int, vagy objektum... a 3. 4. 5. paraméter szintúgy különböző típusok lehetnének.

    Azt vágom, hogy kell később vizsgálni, hogy milyen típus, de hogy kell a függvény paramétereit leírni, hogy híváskor elfogadjon akár számot, akár stringet, akár objektumot?

    Előre is köszi

    http://www.flickr.com/photos/34330024@N05/sets/

  • sztanozs

    veterán

    válasz kiskornel #9319 üzenetére

    JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

  • fatal`

    titán

    válasz kiskornel #9319 üzenetére

    Attól függ mit szeretnél, C#-ban nincs union type. Ha csak kiírni ToString()-gel, akkor a #9320-ban említettek is megfelelőek lehetnek.

    Lehet több overloadot csinálni (persze 5 paraméternél ez baromi sok lenne), vagy pedig builder patternre (vagy ahhoz hasonlóra) lehet szükséged, bár ez konstruktornál hasznos.

    Akár típusra pattern matching is játszhat.

    A cél nélkül nehéz megmondani :)

  • petyus_

    senior tag

    válasz kiskornel #9319 üzenetére

    Mutatnál példát könnyebb lenne.

    Így bármennyi paramétert át tudsz adni:
    Method(int x, params object[] obj){}

    De nem tűnik túl tisztának így a kód, ha mutatsz belőle, lehet meg lehet csinálni jobban is.

  • joysefke

    veterán

    LOGOUT blog

    válasz kiskornel #9319 üzenetére

    szvsz:
    -(A) vagy több overloadolt függvény dekalrációt használsz ugyanazzal a függvénynévvel, de különböző paramétertípusokkal , e.g.: void A (int, string, string); void A (int, object, object);
    -(B) vagy egyszerűen object-ként deklarálod a különböző bemenő paramétereket és bent egy type-matching switch statementel eldöntöd a konkrét típust.

    -(C) gondolom tisztában vagy a generikus típus/metódusdeklaráció mikéntjével és nem erre lenne igazából szükséged:
    pld
    public int Foo<T1,T2,T3>(int x, T1 p1, T2 p2, T3 p3){
               
        Console.WriteLine($"{p1.GetType()}  {p2.GetType()} {p3.GetType()}");
        return x;
    }

  • kiskornel

    addikt

    válasz joysefke #9323 üzenetére

    Köszönöm a válaszokat. A cél egy log fájl írása lenne. Bárhol a progiban ahol Catch ágra fut, ott meg kellene hívnom egy errorlog függvényt, aminek az első paramétere, egy int (hol száll el) ... ez tiszta. DE...
    A eset: a második paraméter meg mondjuk egy string (név) , harmadik egy int (ciklusszámláló).
    B eset: a második paraméter egy WebClient (maga az objektum), harmadik param. egy webclient response (a válasz, amit ad), negyedik egy string (URL, ahonnan meg lett az hívva).
    C eset: stb...

    Tehát a paraméterek száma is változik (gondolom optional kell legyenek az elhagyható paraméterek) és még a típusuk is változik össze vissza. A függvény belülről nem gond, a típusazonosítás után már fel lehet dolgozni, de nem akarok tömböt definiálni, mikor hívom a függvényt, csak a paramétereket zárójelben bepakolni, átadni.

    Az átadott paramétereket meg szétbontom, formázom, és kiírom a log fájlba.

    Csak tanulás céljából kérdezem, mert túl sok macera, meg lehet kerülni, máshogy kivitelezni. (meg mert így szokták a nagyok).

    Lenne kérdésem a válaszokkal kapcsolatban is, de ha felteszem, tutti elviszi a témát. :R

    Még1x köszönöm a válaszokat, mindent átguglizok. :)

    http://www.flickr.com/photos/34330024@N05/sets/

  • sztanozs

    veterán

    válasz kiskornel #9324 üzenetére

    Log fájlba az alábbi dolgok kellenek:
    - esemény ideje (UTC vagy timezone megadásával)
    - esemény szintje (amennyiben szükséges)
    - esemény típusa (és/vagy azonosítója)
    - esemény forrása (és vagy forrás azonosítója)
    - esemény sikeressége (ha típus szinten ezt nem különítjük el)
    - esemény üzenet

    Tehát egy logoló kódba nem kell beledobálni mindenféle objektumokat. Azt vagy egy előre definiált esemény-objektummal kell feltölteni, vagy szöveges mezőket megadni.

    [ Szerkesztve ]

    JOGI NYILATKOZAT: A bejegyzéseim és hozzászólásaim a személyes véleményemet tükrözik; ezek nem tekinthetők a munkáltatóm hivatalos állásfoglalásának...

  • joysefke

    veterán

    LOGOUT blog

    válasz kiskornel #9324 üzenetére

    Vannak loggoló frameworkok, pld "Serilog". https://github.com/serilog/serilog/wiki/Getting-Started#example-application

    Itt egy videó https://www.youtube.com/watch?v=ljZpWbuK68s

    A loggolás pedig ennyi:

    catch (Exception ex){
    Log.Error(ex, "Something went wrong. Részletek: {param1} {param2} {param3}", param1, param2, param3);             
    }

    Ha nem teljesítmény kritikus az applikáció akkor a fenti séma jó is...

    mindent átguglizok
    abból semmit nem lehet tanúlni

    [ Szerkesztve ]

  • petyus_

    senior tag

    válasz kiskornel #9324 üzenetére

    Ahogy a többiek is írták, a logger-be nem kéne ilyen logikát rakni, annak már csak azt az adatot kellene átadnod, ami a logba kerül.

    "A függvény belülről nem gond, a típusazonosítás után már fel lehet dolgozni, de nem akarok tömböt definiálni, mikor hívom a függvényt, csak a paramétereket zárójelben bepakolni, átadni."

    Ha mégis így akarod, akkor a params-t használd, ahogy korábban írtam:
    Method(int x, params object[] obj){}
    Itt nem kell létrehoznod semmilyen tömböt, vesszővel elválasztva pakolhatod be a paramétereket, utána a függvényen belül viszont a tömb elemein kell végigmenned.

    [ Szerkesztve ]

  • Keem1

    addikt

    Ezt meg kell osszam veletek skacok :D Nem, nem száll a fejembe a dicsőség, 25 irtó könnyű kérdés, aki ezeket nem tudja szintén 100%-osra megválaszolni, az annyit jelent, hogy még tanulja/tanulnia kell a nyelvet. De azért örülök, hogy puskázás nélkül 25/25 lett :DDD

  • DrojDtroll

    addikt

    Sziasztok!

    Van sok 8MB-os fájlom, amit szeretnék feldolgozni. A fájlok pontosan 2048x2048 db előjel nélküli két byte-os egész számot tartalmaznak binárisan.

    Az első megoldásban két for ciklus segítségével olvastam be 16 bitenként. Próbaként megpróbáltam 64 bitet beolvasni és biteltolással előállítani a 64 bites számból a 4db 16 biteset. Úgy néz ki ez a módszer kb. kétszer olyan gyors mint a 16 bites.

    Különböző tömböket kapok és nem tudom hol a hiba.

    Mi okozza a különbséget?

    Pastebin link

    [ Szerkesztve ]

  • joysefke

    veterán

    LOGOUT blog

    válasz DrojDtroll #9331 üzenetére

    Nincs időm kipróbálni, de nekem egyáltalán nem szimpatikus egy ilyen nagy fájlnak a mini adagokban való szekvenciális olvasgatása.

    1, Miért nem a sima stream Read metódussal olvasol azonnal byte[] tömbbe?
    2, Én megpróbálnám a bufferméreteket manuálisan feljebb húzni. Alapból csak valami ici-pici bufferekkel dolgozik. (nekem pár 10KB rémlik)
    3, Nem mintha itt számítania kellene de te itt ugye 4M elemen iterálsz át egy szoros for () ciklusban => ha nem fájlműveletet végeznél, akkor már ez is bizonyos helyzetekben indokolatlanul lassú (4M tömbhatár ellenőrzés az indexerekre+ ellenőrzés az iterátoron, szerk: mondjuk 4M az még nem túl sok..)
    (4, miért int tömbben-ben tárolod a short értékeidet?)

    5, a két kód ránézésre nem ugyanazt csinálja. a második konkrétan elcseszettnek tűnik.
    64bitenként olvasol és ugyanúgy 4M-szor mint amikor 16 bitenként olvastál????

    [ Szerkesztve ]

  • joysefke

    veterán

    LOGOUT blog

    válasz joysefke #9332 üzenetére

    Uhh az utolsó pontot visszavonom, látom, hogy a belső ciklus 4esével változik növeli a törzsön belül a ciklusváltozót. késő van na :B
    Nyilván segít neki, hogy negyed annyi io van. De igazán jo szvsz akkor lesz ha nagy puffer mellett byte tömböt olvasol be addig amíg van mit olvasni.

    [ Szerkesztve ]

  • DrojDtroll

    addikt

    válasz joysefke #9332 üzenetére

    Megvan mi volt a hiba forrása: nem úgy vannak tárolva az adatok ahogy azt elképzeltem.
    Nem sorrendben vannak leírva a byte-ok hanem fordított sorrendben. Meg kell cserélni azt a két byte-ot ami a számot tárolja.

  • joysefke

    veterán

    LOGOUT blog

    válasz DrojDtroll #9331 üzenetére

    for (int i = 0; i < heigth; i++)
    {
        for (int j = 0; j < width; j++)
        {
            result[j, i] = reader.ReadUInt16();
        }
    }

    Itt van még egy olyan probléma (mindkét példádban), hogy úgy iterálsz át egy nagy többdimenziós tömbön, hogy a belső ciklusod nem a tömb legjobboldalibb dimenzióján iterál.

    C#-ban a többdimenziós tömbök (A[,,,]) row-major ként vannak a memóriában, tehát a legjobb oldalibb dimenzió egymás melletti elemei a memóriában egymás mellett lesznek. az A[100, 50] elem mellett az A[100,51] elem van. Ezzel szemben az A[101,50] az teljesen máshol van, a te esetedben (2048) elemmel később mint az A[100,50], tehát mivel int tömbről van szó, 8KB-tal később van. Az hogy itt csak írsz és nem olvasol kb mindegy, mert nyilván egy egész cache line lesz írva/olvasva.

    A helyzeten cache-line szempontből még (valószínűleg) tovább ront itt, hogy kettő hatványonként iterálsz. ilyen problémák nagy mátrixok szorzásánál vannak

    [ Szerkesztve ]

  • joysefke

    veterán

    LOGOUT blog

    válasz DrojDtroll #9334 üzenetére

    Igen, én is észrevettem, de szvsz nem a forrásadatokkal van a probléma, hanem a két metódusod nem ugyanazt a bytesorrendet használja, tehát a tömbök tartalma amelyeket visszaadnak sem ugyanaz lesz.

    Amikor a második metódusban streamből beolvasol egy ulongot, akkor a ReadUInt64() figyelembe veszi az x86 bytesorrendjét: a változónak a kisebb helyiértékű byteja van alacsonyabb címen (little endian). Ha a streamed sorrendben ezeket a byteoket tartalmazza:
    1, 0x01; 2, 0x02; 3; 0x03; 4, 0x04; 5; 0x05; 6, 0x06; 7, 0x07;8, 0x08;

    akkor a kiolvasott ulong értéke az 0x08'07'06'05'04'03'02'01 lesz, szemben azzal a sorrenddel amit a fileban látsz.

    Ha ezt a részt fordított sorrendbe raknád, akkor pont ugyanazt a tömböt adná vissza a kettő metódusod.

                            result[++j, i] = (ushort)(r >> 48);
                            result[++j, i] = (ushort)(r >> 32);
                            result[++j, i] = (ushort)(r >> 16);
                            result[++j, i] = (ushort)r;

    [ Szerkesztve ]

  • DrojDtroll

    addikt

    válasz joysefke #9335 üzenetére

    Köszönöm a segítséget. A forráson nem tudok változtatni, ott van rossz más sorrendben az adat. A további feldolgozás a megszokott (legjobb oldalibb) indexelést használja. Az adatok későbbi feldolgozása miatt van szükség az int-ben való tárolásra.

  • joysefke

    veterán

    LOGOUT blog

    válasz DrojDtroll #9337 üzenetére

            public static int[,] Get4mIntArrBufferedSpan(string fileName)
            {
                var sw = new Stopwatch();
                uint heigth = 2048;
                uint width = heigth;
                var result = new int[heigth, width];
                var buffSize = sizeof(ushort) * heigth;
                var buff = new byte[buffSize];
                using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize: 1024 * 1024))
                {
                    sw.Start();
                    for (int w = 0; w < width; w++)
                    {
                        int chunk = 0;
                        while (chunk < buffSize)
                            chunk += fs.Read(buff, chunk, (int)buffSize - chunk);
                        
                      var shortArr = MemoryMarshal.Cast<byte, ushort>(buff);
                        for (int h = 0; h < heigth; h++)
                          result[h, w] = shortArr[h];
                    }
                    sw.Stop();
                    Console.WriteLine($"{nameof(Get4mIntArrBufferedSpan)} took {sw.ElapsedMilliseconds}ms");
                }
                return result;
            }

    Nekem a fenti kód pontosan ugyanazt az eredmény tömböt dobja ki mint a te első metódusod. A különbség annyi, hogy a itt while ciklus megpróbál egyszerre 4096byteot (2048db ushort) kiolvasni a streamből, a kiolvasott byte tömböt castolja ushort-tömbre azzal pedig feltölti egy oszlopodat.

    Szóval itt is rossz a tömb bejárási sorrendje, de a Stream.Read() metódus úgy tűnik, hogy ennyivel hatékonyabb, mint egyenként ushortokat olvasgatni. (nálam pontosan duplázódott a sebesség)

    A fenti kódban ha a mátrix bejárási sorrendje "normalizálódna" akkor további 3x lenne gyorsabb. ==> tehát igen, itt a processzor fogja vissza a fájlműveletet :)

    Ebben az esetben lenne értelme egyszerre 2048db elemnél többet is olvasni. Az még dobna rajta.

    [ Szerkesztve ]

  • Keem1

    addikt

    Srácok, Linq segítséget kérnék.

    Ez így az objektumot adja vissza:
    System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).Select(ip => ip.ToString()).ToList();

    Addig jó, hogy ha lehagyom a végéről a selectet, akkor ugye az eredmény List<IpAddress>, viszont nekem List<string> kellene, de nem az ojjektum nevéről :DDD :R

  • joysefke

    veterán

    LOGOUT blog

    válasz Keem1 #9339 üzenetére

    ???

    Az eredmény egy List<string> ami stringként ábrázolt IP-címeket tartalmaz, hol itt a probléma?

  • Keem1

    addikt

    válasz joysefke #9340 üzenetére

    Hátöö.... nem.. :D
    Nem az IP lesz stringként, hanem az object neve.

    Szerk... ja de. :U Szóval próbálkoztam, megterveztem a kérdést, majd megírtam a jó megoldást és végül azt posztoltam ide? Ez történhetett? :DDD

    Szóval megvan a megoldás, nincs kérdés, sorry! :B

    [ Szerkesztve ]

  • Tomi_78

    tag

    Sziasztok!
    Most kezdtem kóstolgatni a C# programozást, és ehhez egy kis grafikus programot írnék SharpDevelop környezetben. Viszont a programom futtatásakor azt írja ki, hogy:
    "Az "egydenever" név nem szerepel ebben a környezetben"
    illetve a DrawImage-ben a két utolsó paramétert (srcRect és units) nem ismeri, bár nem is tudom, hogy ide miket kéne megadni.
    Tudnátok segíteni ennek a két hibajelenségnek a megoldásában? Íme a kódom:
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Windows.Forms;

    namespace Animacios
    {
        /// <summary>
        /// Description of MainForm.
        /// </summary>
        
        public partial class MainForm : Form
        {    
            Bitmap deneverkepe1 = new Bitmap("kepei\\kisdenever1bmp.bmp");
            Bitmap deneverkepe2 = new Bitmap("kepei\\kisdenever2bmp.bmp");
            
            class Deneverek
            {
                public int dirx,diry,kepe;
            };
            
            public MainForm()
            {
                //
                // The InitializeComponent() call is required for Windows Forms designer support.
                //
                InitializeComponent();
                //
                // TODO: Add constructor code after the InitializeComponent() call.
                //
                deneverkepe1.MakeTransparent();
                deneverkepe2.MakeTransparent();
                
                Deneverek[] egydenever = new Deneverek[3];
                int svsz;
                for (int i=0; i<3; i++) {
                    egydenever[i]= new Deneverek();
                    System.Random vsz = new System.Random();
                    svsz = vsz.Next(1);
                    if (svsz==0) {
                        egydenever[i].dirx = -1;
                    } else {
                        egydenever[i].dirx = 1;
                    };
                    svsz = vsz.Next(1);
                    if (svsz==0) {
                        egydenever[i].diry = -1;
                    } else {
                        egydenever[i].diry = 1;
                    };
                    svsz = vsz.Next(1);
                    if (svsz==0) {
                        egydenever[i].kepe = 0;
                    } else {
                        egydenever[i].kepe = 1;
                    };
                };
            }
            void AnimIdozitoTick(object sender, EventArgs e)
            {
                for (int i=0; i<3; i++) {
                    if (egydenever[i].kepe==0) {
                        egydenever[i].kepe=1;
                    }
                    else {
                        egydenever[i].kepe=0;
                    };
                };
            }
            void MozgIdozitoTick(object sender, EventArgs e)
            {
                for (int i=0; i<3; i++) {
                    switch (egydenever[i].dirx) {
                        case -1:
                            if (egydenever[i].Left>0) {
                                egydenever[i].Left-=4;
                            }
                            else egydenever[i].dirx*=-1;
                        break;
                        case 1:
                            if (egydenever[i].Left<800-egydenever[i].Width) {
                                egydenever[i].Left+=4;
                            }
                            else egydenever[i].dirx*=-1;
                        break;
                    };
                    switch (egydenever[i].diry) {
                        case -1:
                            if (egydenever[i].Top>0) {
                                egydenever[i].Top-=4;
                            }
                            else egydenever[i].diry*=-1;
                        break;
                        case 1:
                            if (egydenever[i].Top<600-egydenever[i].Height) {
                                egydenever[i].Top+=4;
                            }
                            else egydenever[i].diry*=-1;
                        break;
                    };
                };
            }
            void MainFormPaint(object sender, PaintEventArgs e)
            {
                for (int i=0; i<3; i++) {
                    if (egydenever[i].kepe==0) {
                        e.Graphics.DrawImage(deneverkepe1,egydenever[i].Left,egydenever[i].Top,srcRect, units);
                    }
                    else {
                        e.Graphics.DrawImage(deneverkepe2,egydenever[i].Left,egydenever[i].Top,srcRect, units);
                    }
                }
            }
        }
    }

  • Alexios

    veterán

    válasz Tomi_78 #9342 üzenetére

    Szia,

    Nem teljesen értem a kódodat, ezt valahonnan kimásoltad? A problémák amik előjöttek azért vannak, mert olyan változókat használsz amik nincsenek sehol deklarálva.
    Pl. az srcRect és units változókat miért adtad meg a DrawImage-ben, ha nincsenek is ilyenjeid?

    Az egydenever változót használod minden metódusban, pedig a konstruktorban, mint lokális változó hozod létre. Ha egy metóduson belül hozol létre egy változót, akkor az csak azon a metóduson belül fog élni, máshol nem, ezt javíthatod a kódon belül pl. így:
    Bitmap deneverkepe1 = new Bitmap("kepei\\kisdenever1bmp.bmp");
    Bitmap deneverkepe2 = new Bitmap("kepei\\kisdenever2bmp.bmp");
    Deneverek[] egydenever;

    majd később már csak ehhez rendelsz értéket:
    egydenever = new Deneverek[3];
    int svsz;

    De érdemes lenne első körben a nyelv alapjait is átnézned.

    Illetve miért pont SharpDevelop, ami évek óta discontinued állapotban van?

    [ Szerkesztve ]

  • Tomi_78

    tag

    válasz Alexios #9343 üzenetére

    Szia Alexios!

    Köszönöm a választ; ezzel egyúttal azt a kérdésemet is megválaszoltad, hogy kezdőérték nélküli, dinamikus tömböt hogyan lehet létrehozni. :K
    Még javítottam a kódomon annyit, hogy a képe egy változóba kerüljön, tehát:
    class Deneverek
            {
                public int dirx,diry;
                public Bitmap kepe;
           };                      

    (...)
    if (svsz==0) {
                        egydenever[i].kepe = deneverkepe1;
                    } else {
                        egydenever[i].kepe = deneverkepe2;
                    };

    De ezek után pl. a kirajzolásban nem ismeri fel a képhez tartozó Left és Top változókat:
    void MainFormPaint(object sender, PaintEventArgs e)
            {
                for (int i=0; i<3; i++) {
                        e.Graphics.DrawImage(egydenever[i].kepe,egydenever[i].kepe.Left,egydenever[i].kepe.Top,egydenever[i].kepe.Width,egydenever[i].kepe.Height);
                }
            }

    Ez miért van?
    És hogy miért pont SharpDevelop? Martonxnek is válaszolva: már régebben a gépemen pihen letöltve és csak most vettem elő. Az tetszett benne annakidején, hogy ingyenes és kicsi: csak letöltöd, kitömöríted és használatra kész. Nem tudom, van-e még ilyen fejlesztőkörnyezet, de nekem egyelőre bejön. :K Azt viszont én is sajnálom, hogy már nem fejlesztik tovább a készítői.

  • Tomi_78

    tag

    Bocs, az előbb javítottam és láttam, hogy nem kezdőérték nélküli a Deneverek tömb... Így javítottam a programomon, de most csak egy denevér jelenik meg, az sem animálódik és nem is mozog:
    namespace Animacios
    {    
        public partial class MainForm : Form
        {    
            Bitmap deneverkepe1 = new Bitmap("kepei\\kisdenever1bmp.bmp");
            Bitmap deneverkepe2 = new Bitmap("kepei\\kisdenever2bmp.bmp");
            
            class Deneverek
            {
                public int dirx,diry,xhely,yhely;
                public Bitmap kepe;
            };
            
            Deneverek[] egydenever;
            
            public MainForm()
            {
                //
                // The InitializeComponent() call is required for Windows Forms designer support.
                //
                InitializeComponent();
                //
                // TODO: Add constructor code after the InitializeComponent() call.
                //
                deneverkepe1.MakeTransparent();
                deneverkepe2.MakeTransparent();
                
                egydenever = new Deneverek[3];
                int svsz;
                for (int i=0; i<3; i++) {
                    egydenever[i]= new Deneverek();
                    System.Random vsz = new System.Random();
                    svsz = vsz.Next(1);
                    if (svsz==0) {
                        egydenever[i].dirx = -1;
                    } else {
                        egydenever[i].dirx = 1;
                    };
                    svsz = vsz.Next(1);
                    if (svsz==0) {
                        egydenever[i].diry = -1;
                    } else {
                        egydenever[i].diry = 1;
                    };
                    svsz = vsz.Next(1);
                    if (svsz==0) {
                        egydenever[i].kepe = deneverkepe1;
                    } else {
                        egydenever[i].kepe = deneverkepe2;
                    };
                    egydenever[i].xhely=vsz.Next(1,800-egydenever[i].kepe.Width);
                    egydenever[i].yhely=vsz.Next(1,600-egydenever[i].kepe.Height);
                };
            }
            void AnimIdozitoTick(object sender, EventArgs e)
            {
                for (int i=0; i<3; i++) {
                    if (egydenever[i].kepe==deneverkepe1) {
                        egydenever[i].kepe=deneverkepe2;
                    }
                    else {
                        egydenever[i].kepe=deneverkepe1;
                    };
                };
            }
            void MozgIdozitoTick(object sender, EventArgs e)
            {
                for (int i=0; i<3; i++) {
                    switch (egydenever[i].dirx) {
                        case -1:
                            if (egydenever[i].xhely>0) {
                                egydenever[i].xhely-=4;
                            }
                            else egydenever[i].dirx*=-1;
                        break;
                        case 1:
                            if (egydenever[i].xhely<800-egydenever[i].kepe.Width) {
                                egydenever[i].xhely+=4;
                            }
                            else egydenever[i].dirx*=-1;
                        break;
                    };
                    switch (egydenever[i].diry) {
                        case -1:
                            if (egydenever[i].yhely>0) {
                                egydenever[i].yhely-=4;
                            }
                            else egydenever[i].diry*=-1;
                        break;
                        case 1:
                            if (egydenever[i].yhely<600-egydenever[i].kepe.Height) {
                                egydenever[i].yhely+=4;
                            }
                            else egydenever[i].diry*=-1;
                        break;
                    };
                };
            }
            void MainFormPaint(object sender, PaintEventArgs e)
            {
                for (int i=0; i<3; i++) {
                        e.Graphics.DrawImage(egydenever[i].kepe,egydenever[i].xhely,egydenever[i].yhely,egydenever[i].kepe.Width,egydenever[i].kepe.Height);
                }
            }
        }
    }

  • Tomi_78

    tag

    válasz Tomi_78 #9346 üzenetére

    Na végre, minden működik, kivéve hogy a képek villognak egy kissé. Ezt nem lehet valahogy kiküszöbölni? Az Invalidate(); függvény ennyire akadozna?

  • Keem1

    addikt

    válasz Tomi_78 #9342 üzenetére

    Ahogy látom, nem csak C#, hanem úgy általában objektumorientált programozási alapok is csiszolásra szorulnak. Én nem vagyok tanár, és a topik témája is bőven kimerül a tanításban, de én a következőket javasolnám neked:

    - rengeteg jó forrás van (leginkább angol nyelven), mégis egy egyszerű, könnyen tanulható és magyar nyelvű könyvet javasolnék: Sipos Marianna: Programozás élesben - C# (megadja a kezdő löketet, az abszolút alapokat)
    - kezdésnek én WinForms helyett console-ban gyakorolnék, alapoznék. Ha ez flottul megy, akkor jöhet az ablakozás. Az ablakozás mindaddig várhat, míg a nyelv alapjait meg nem ismered: keywordök, objektumok, névterek, metódusok, láthatóság, öröklődés, stb.

    Tényleg csupa jó tanácsként szánom a fentieket, és elnézést, ha tévedtem, rosszul mértem fel, hogy nem csak C#-ban, de úgy alapból OO programozásban is abszolút kezdő vagy.
    Amúgy meg a C# szerintem egy szuper nyelv: egyszerű, könnyen kezelhető, de mégis sokoldalú. Főleg a rengeteg forrásanyag, tutorial, 3rd party libraryk miatt.

  • Tomi_78

    tag

    válasz Keem1 #9348 üzenetére

    Utánanézek a könyvnek, bár nekem is vannak programozással (C++ és C# is) foglalkozó köteteim, igaz, végigolvasni még egyet sem volt időm vagy türelmem. Inkább célirányosan kutatok, ha szembesülök valami problémával, mert azt már nem kell nekem elmagyarázni, hogy mi a tömb, az elágazás vagy a ciklus, hanem inkább az olyan dolgokat, amik az adott fejlesztőkörnyezet sajátosságai, mint pl. hogy C#-ban hol kell elhelyezni a globális változókat a kódban vagy hogy bizonyos deklarálásokat milyen formában kell megadni.
    Lehet, hogy velem van a hiba, hogy szájbarágósan és nem bikkfanyelven várom el a szakkönyvektől is a magyarázatokat, dehát ez van.
    Az OOP lényegét is úgy mondanám el, hogy tagolva vannak benne a dolgok, az események csak azok szükségessége esetén hajtódnak végre, és nem folyamatosan, ciklikusan figyeli a program az összes tennivalót.

  • disy68

    aktív tag

    válasz Tomi_78 #9349 üzenetére

    "Az OOP lényegét is úgy mondanám el, hogy tagolva vannak benne a dolgok, az események csak azok szükségessége esetén hajtódnak végre, és nem folyamatosan, ciklikusan figyeli a program az összes tennivalót."

    Hmm. Az egymondatos definíció mindig nehéz, de azért az események nem igazán tartoznak ide.

    OOP alapelvek:
    - Absztrakció
    - Polimorfizmus
    - Öröklődés
    - Egységbezárás

    “Yeah, well, you know, that’s just, like, your opinion, man.” — The Dude

Új hozzászólás Aktív témák