folder Tahribat.com Forumları
linefolder C#, Asp.Net, .Net Core
linefolder C#, Async Ve Çözemediğim Bir Problem



C#, Async Ve Çözemediğim Bir Problem

  1. KısayolKısayol reportŞikayet pmÖzel Mesaj
    palin
    palin's avatar
    Kayıt Tarihi: 09/Temmuz/2010
    Erkek

    Merhabalar,

     

    Sebebini çözemediğim bir hatayla karşı karşıyayım. Şöyle anlatmaya çalışayım:

    Elimde 2 class var. Bunlardan birisi ana program, diğeri async bağlantılar yapan bir TCPClient içeren başka bir class. Bu classta gelen mesajın ana programa yönlendirilmesi için bir deligate var, o deligate içinde de ana programda bulunan bir methoda referans var. Ana programa verileri alabiliyorum, gelen veri bir string. Fakat, peşpeşe çok fazla veri gelirse, o string üzerinde çalışamıyorum. string.IndexOf, StartsWith vs hepsi yanlış bilgi veriyor, fakat sadece string i yazdırdığımda doğru string olduğunu görebiliyorum. Veri akışını yavaşlatırsam hiç bir sıkıntı olmadan çalışabiliyorum. Bunun nedeni ne olabilir?

     

    Kodun gerekli kısmını kopyalıyorum:

     

    İlk önce ana programda çalışan method, test için:

     

    public static void serverConnection_serverMessage(string message)

    {

    Console.WriteLine(message); // doğru mesaj olduğunu görebiliyorum.

    Console.WriteLine(message.IndexOf(" ").ToString()); // Normal bir durumda gönderirsem index i veriyor. Fakat peşpeşe 50 mesaj gönderirsem 1 saniye içinde vs. string de boşluk olmadığını idda ediyor.

    }

     

    Bu da bağlantıyı izleyen kod:

     

    public event serverMessageEventHandler serverMessage;

            public delegate void serverMessageEventHandler(string message);

     

    public Baglanti(string address, int port)

            {

                            this.connection.Connect(address, port);

     

                //Baglanabildiyse

                if (this.connection.Connected)

                {

                    //Yeni mesajlari al

                    connection.Client.BeginReceive(this.buffer, 0, this.buffer.Length, SocketFlags.None, new AsyncCallback(this.handleServerMessage), null);

                }

            }

     

            //Mesaj geldiginde

            void handleServerMessage(IAsyncResult result)

            {

                //Uzunlugu lazim

                int receivedCount;

                try

                {

                    receivedCount = connection.Client.EndReceive(result);

                }

                catch

                {

                    //Hata varsa yapacak bir sey yok

                    return;

                }

     

                //0 kapandi demek

                if (receivedCount == 0)

                {

                    this.Disconnect();

                    return;

                }

     

     

              //Ana programa gonder

                this.serverMessage(Encoding.Default.GetString(buffer, 0, receivedCount));

     

              //Bir sonraki mesaji bekle

                connection.Client.BeginReceive(this.buffer, 0, this.buffer.Length, SocketFlags.None, new AsyncCallback(this.handleServerMessage), null);

            }

     


  2. KısayolKısayol reportŞikayet pmÖzel Mesaj
    YeniHarman
    YeniHarman's avatar
    Kayıt Tarihi: 17/Haziran/2012
    Erkek

    Ana programda stringin kopyasıyla çalıştıığınızda ne sonuç veriyor peki?


    Olaylara karışmayın!
  3. KısayolKısayol reportŞikayet pmÖzel Mesaj
    palin
    palin's avatar
    Kayıt Tarihi: 09/Temmuz/2010
    Erkek
    YeniHarman bunu yazdı

    Ana programda stringin kopyasıyla çalıştıığınızda ne sonuç veriyor peki?

    Başka bir stringe aktarıp deneyince de aynı hocam. Miktar artınca bozuluyor hemen


  4. KısayolKısayol reportŞikayet pmÖzel Mesaj
    YeniHarman
    YeniHarman's avatar
    Kayıt Tarihi: 17/Haziran/2012
    Erkek

    İlginç. Bununla ilgili bir şey de bulamadım.

    Yanlış değer dönen yere breakpoint koyup watch kısmında incelediniz mi? Olmadı .net fw sürümünü değiştirip deneyin.


    Olaylara karışmayın!
  5. KısayolKısayol reportŞikayet pmÖzel Mesaj
    palin
    palin's avatar
    Kayıt Tarihi: 09/Temmuz/2010
    Erkek
    YeniHarman bunu yazdı

    İlginç. Bununla ilgili bir şey de bulamadım.

    Yanlış değer dönen yere breakpoint koyup watch kısmında incelediniz mi? Olmadı .net fw sürümünü değiştirip deneyin.

    Kodu deneme imkanınız varsa bir de siz bakar mısınız hocam? Çok garip şeyler dönüyor. WriteLine(gelenString + ": test"); yazıyorum, sadece gelen stringi yazıyor, gerisini sadece bazılarına yazıyor. Belli bir düzen de yok. Bazen birinci ve dördüncü mesaja, bazen onbirinci...


  6. KısayolKısayol reportŞikayet pmÖzel Mesaj
    buzukatak
    buzukatak's avatar
    Kayıt Tarihi: 27/Haziran/2010
    Erkek

    Çok daha derin bir sorun değilse ki sanmıyorum, GetString ile metne çevirdiğin veride yine büyük ihtimalle sonda null bayt var gibi görünüyor.

    this.serverMessage(Encoding.Default.GetString(buffer, 0, receivedCount));

    satırını aşağıdaki ile değiştirerek deneyebilirsin. Burada yapılan iş kabaca metinden NULL karakterlerini temizlemek.

    //Ana programa gonder
    string hamMetin = Encoding.Default.GetString(buffer, 0, receivedCount);
    string temizMetin = hamMetin.Replace("\0", "");
    this.serverMessage(temizMetin);
    

     


    anlıyorum.
  7. KısayolKısayol reportŞikayet pmÖzel Mesaj
    palin
    palin's avatar
    Kayıt Tarihi: 09/Temmuz/2010
    Erkek
    buzukatak bunu yazdı

    Çok daha derin bir sorun değilse ki sanmıyorum, GetString ile metne çevirdiğin veride yine büyük ihtimalle sonda null bayt var gibi görünüyor.

    this.serverMessage(Encoding.Default.GetString(buffer, 0, receivedCount));

    satırını aşağıdaki ile değiştirerek deneyebilirsin. Burada yapılan iş kabaca metinden NULL karakterlerini temizlemek.

    //Ana programa gonder
    string hamMetin = Encoding.Default.GetString(buffer, 0, receivedCount);
    string temizMetin = hamMetin.Replace("\0", "");
    this.serverMessage(temizMetin);
    

     

    Denedim hocam, hala aynı sonucu alıyorum. newline ları temizledim, null ları temizledim.


  8. KısayolKısayol reportŞikayet pmÖzel Mesaj
    MhmdAlmz
    MhmdAlmz's avatar
    Kayıt Tarihi: 09/Ağustos/2015
    Erkek

    Normal değil mi ?

    Sen Async çalıştırıyorsun , O an Socketten aynı anda 2 veri geliyor ve sen 1 veriyi yazarken diğer veriyi de üstüne yazıyorsun.

    Yani

    ABC -> geldi

    DEF -> geldi

    ADBCEF oldu ; normal bir yaklaşım. Senin buna çözüm bulman gerekiyor hocam.

    Bence flag mantığını kullanmalısın. Yani bir veriyi stringe doldurmadan diğer veriyi yazdırmaman gerekiyor.

    Her Async hadle fonksiyonu çağırıldığında Class oluştur bir tane

     

    class : 
    UUID;
    Data

     

    şeklinde bunu da array'e at. Fonksiyon handle pozisyonuna geçtiğinde uuid ata fonksiyonun başında sen bu uuid fonksiyonuyla iş yap. Senin her datan o uuidye yazılsın ordan oku. Sen tek değişkene atıp okumaya çalışıyorsun .

    EDİT ; hocam birde swapping işlemlerine dikkat et. Aynı anda 2 stringin bitme ihtimali var yada kaç tane Thread var ise işlemcide o kadar sayınca değişkenin aynı bitme ihtimali var. Ben bunu Linux tarafında her porttan gelen veri C++ ile dinliyorum Ramde bir adreste tutuyorum. veriyi okurkende C++ daki adresi ilgili programlama diline aktarıp veriyi o şekilde okuyorum. Daha hızlı oluyor C++ da socket yönetimi daha basit. Proccessleri vs de kontrol ettiğin için hangi işlem ne zaman bitmiş data neymiş hangi socketid den gelmiş alayının logunu tutabiliyorsun.

    MhmdAlmz tarafından 31/Ara/18 11:58 tarihinde düzenlenmiştir

    Andolsun kuşluk vaktine ve dindiği zaman o geceye ki, Rabbin sana veda etmedi ve darılmadı! Ve kesinlikle senin için sonu önünden (ahiret dünyadan) daha hayırlıdır. ileride Rabbin sana verecek de hoşnut olacaksın! O, seni bir yetim iken barındırmadı mı? Seni, yol bilmez iken (doğru) yola koymadı mı? Seni bir yoksul iken zengin etmedi mi? Öyle ise, sakın yetime kahretme (onu horlama)! El açıp isteyeni de azarlama! Fakat Rabbinin nimetini anlat da anlat!
  9. KısayolKısayol reportŞikayet pmÖzel Mesaj
    palin
    palin's avatar
    Kayıt Tarihi: 09/Temmuz/2010
    Erkek
    MhmdAlmz bunu yazdı

    Normal değil mi ?

    Sen Async çalıştırıyorsun , O an Socketten aynı anda 2 veri geliyor ve sen 1 veriyi yazarken diğer veriyi de üstüne yazıyorsun.

    Yani

    ABC -> geldi

    DEF -> geldi

    ADBCEF oldu ; normal bir yaklaşım. Senin buna çözüm bulman gerekiyor hocam.

    Bence flag mantığını kullanmalısın. Yani bir veriyi stringe doldurmadan diğer veriyi yazdırmaman gerekiyor.

    Her Async hadle fonksiyonu çağırıldığında Class oluştur bir tane

     

    class : 
    UUID;
    Data

     

    şeklinde bunu da array'e at. Fonksiyon handle pozisyonuna geçtiğinde uuid ata fonksiyonun başında sen bu uuid fonksiyonuyla iş yap. Senin her datan o uuidye yazılsın ordan oku. Sen tek değişkene atıp okumaya çalışıyorsun .

    Merhaba hocam, benim anlayamadığım şey şu. Mesela  bir örnek vereyim.
    Benim veriyi işleyen methodumun içine,

    WriteLine(GelenVeri + ": test");

    yazıyorum mesela, veriyi aldığını görebiliyorum. Ama veriyle test stringini birleştiremiyor. Hızlıca sockete 1 ile 50 arası sayılar yazdırırsam mesela, şöyle oluyor genelde:

    1: test

    2

    3

    4

    5

    6

    7: test

    8

    9

    ...

     

    Veriyi aldıktan sonra işleyebilmesi gerek miyor mu? O WriteLine ın altına tekrardan GelenVeri yi yazdırırsam görebiliyorum ki veri değişmemiş.


  10. KısayolKısayol reportŞikayet pmÖzel Mesaj
    MhmdAlmz
    MhmdAlmz's avatar
    Kayıt Tarihi: 09/Ağustos/2015
    Erkek

    Hocam tam olarak programın yada algoritmanın çalışma mantığını bilmiyorum.

    Fakat şöyle dene önce  A istemcisi (server veya client artık neyse bundan sonra A istemcisi diyeceğim) B istemcisine veri gönderiyor

    Sen A dan B ye tek tek 1 den 50 ye kadar veri gönderiyorsun.

    Async fonksiyonu çalışırken 

    1:test

    2

    3

    4

    5

    6

    7:test

    mi yazyor ? 

    yani 1 i alınca test yazıyor 7 ye kadar test yazmıyor ? Doğru mu anlıyorum ?

     

    Böyle bir şey mümkün değil yada oradaki çalıştırdığın socketin data boyutunca veri gönderiyor ki bu saçma bir şey olur. Yani söylediğin şey mantıksız.

    Yada benim sana anlattığım gibi bir olay örgüsü var.

    Sen string'e 1 i yazdın sonra 1:test çıktıyı üretti. O ara Socket 6 tane daha data gönderdi.

    sen 6 datayı da aynı anda o değişkene yazdın oldu mu sana

    2

    3

    4

    5

    6

    7

    daha sonra :test ekledi sonuna senin algoritman ve sonuç çıktısı

    2

    3

    4

    5

    6

    7:test oldu ?

     

    Bence senin sorunun Multi Thread hocam socket ile ilgili değil. Benim sana dediğim gibi eğer her datayı bir UUID ile tutarsan LinkedList yada bir Stack mantığı ile FIFO mantığını kullanarak O Arrayde yada listede data oldukça okursun. 


    Andolsun kuşluk vaktine ve dindiği zaman o geceye ki, Rabbin sana veda etmedi ve darılmadı! Ve kesinlikle senin için sonu önünden (ahiret dünyadan) daha hayırlıdır. ileride Rabbin sana verecek de hoşnut olacaksın! O, seni bir yetim iken barındırmadı mı? Seni, yol bilmez iken (doğru) yola koymadı mı? Seni bir yoksul iken zengin etmedi mi? Öyle ise, sakın yetime kahretme (onu horlama)! El açıp isteyeni de azarlama! Fakat Rabbinin nimetini anlat da anlat!
  11. KısayolKısayol reportŞikayet pmÖzel Mesaj
    palin
    palin's avatar
    Kayıt Tarihi: 09/Temmuz/2010
    Erkek
    MhmdAlmz bunu yazdı

    Hocam tam olarak programın yada algoritmanın çalışma mantığını bilmiyorum.

    Fakat şöyle dene önce  A istemcisi (server veya client artık neyse bundan sonra A istemcisi diyeceğim) B istemcisine veri gönderiyor

    Sen A dan B ye tek tek 1 den 50 ye kadar veri gönderiyorsun.

    Async fonksiyonu çalışırken 

    1:test

    2

    3

    4

    5

    6

    7:test

    mi yazyor ? 

    yani 1 i alınca test yazıyor 7 ye kadar test yazmıyor ? Doğru mu anlıyorum ?

     

    Böyle bir şey mümkün değil yada oradaki çalıştırdığın socketin data boyutunca veri gönderiyor ki bu saçma bir şey olur. Yani söylediğin şey mantıksız.

    Yada benim sana anlattığım gibi bir olay örgüsü var.

    Sen string'e 1 i yazdın sonra 1:test çıktıyı üretti. O ara Socket 6 tane daha data gönderdi.

    sen 6 datayı da aynı anda o değişkene yazdın oldu mu sana

    2

    3

    4

    5

    6

    7

    daha sonra :test ekledi sonuna senin algoritman ve sonuç çıktısı

    2

    3

    4

    5

    6

    7:test oldu ?

     

    Bence senin sorunun Multi Thread hocam socket ile ilgili değil. Benim sana dediğim gibi eğer her datayı bir UUID ile tutarsan LinkedList yada bir Stack mantığı ile FIFO mantığını kullanarak O Arrayde yada listede data oldukça okursun. 

    Keşke sorunum multithread de olsaymış hocam. Kaç saattir bu koda bakıyorum, yanlış bir şey göremiyorum. Sorun bu kısımda değild de veriyi gönderdiğim yerdeymiş. Ekstradan 2 byte gönderiyormuş, o yüzden ben gelen veriyi işleyemiyormuşum. Çözüldü sonunda :D


Toplam Hit: 4904 Toplam Mesaj: 13
c# async