Şimdi Ara

.net ile MultiThereading

Daha Fazla
Bu Konudaki Kullanıcılar: Daha Az
1 Misafir - 1 Masaüstü
5 sn
4
Cevap
0
Favori
805
Tıklama
Daha Fazla
İstatistik
  • Konu İstatistikleri Yükleniyor
0 oy
Öne Çıkar
Sayfa: 1
Giriş
Mesaj
  • Selamlar

    Temel olarak, elimde mevcut olan veri tabanından sorgulama yapıp, sonuçları datagridview nesnesine göstermek istiyorum.(Bu işlemi yapıyorum.)
    Tabi bu işlem yapılırken programın kilitlenmemesi(Yanıt vermeme) ve formu hareket ettirebilmesi. Yani arama butonuna basıldığından sonuçlar bulunup listeleme yapılana tek formun kilitlenmemesini istiyorum. Bunu belirtmemin sebebi, Veri tabanında kayıt miktarı fazla, fazla olduğu içinde arama işlemi biraz uzun sürüyor ve sonuçlar bulundukdan sonrada datagridview nesnesine aktarmasıda uzun sürüyor. Bu işlemde formu, yani programı sonuçlar listelene tek kilitliyor. Yanıt vermiyor diyor.

    Thereading yöntemi ile sonuçları bulma işlemini yapıyorum ama iş form üzerindeki datagridview nesnesine bağlantı kurduğumda hata ile karşılaşıyorum. Nesneyi kendim yaratıp oluşturduğun nesneyi, form üzerine add işlemi yapdığımda da hata ile karşılaşıyorum.

    Bu işe öneri veya çözüm bulabilecek arkadaşlar şimdiden teşekkürler.







  • Normal bir program kodu sadece tek koldan akar ve aynı anda sadece bir komut çalıştırılabilir. Bu, basit programlar için yeterli olabilir ancak programın yönettiği iş sayısı arttıkça tek yönlü akış yetmemeye başlar ve programın kendi içinde parçalara ayrılıp her parçanın farklı bir görevden sorumlu olmasının sağlanması gerekir. Bir programın birden çok parçaya bölünerek yürütülmesine multithreading, oluşturulan herbir parçacığa da thread(kelime anlamı iplik) denir.

    Thread Oluşturma Ve Yönetme
    Visual Basic 6.0
    Visual Basic 6.0 çok parçacıklı programlar yazmayı mümkün kılacak özel kütüphane veya fonksiyon barındırmaz. Ancak Windowsun kernel32.dll kütüphanesinin fonksiyonları kullanılarak thread oluşturmak ve yönetmek mümkündür:
    Private Declare Function POlustur Lib "kernel32" Alias "CreateThread" ( _
    ByVal lpThreadAttributes As Any, _
    ByVal dwStackSize As Long, _
    ByVal lpStartAddress As Long, _
    lpParameter As Any, _
    ByVal dwCreationFlags As Long, _
    lpThreadID As Long) As Long

    Private Declare Function PDuraklat Lib "kernel32" Alias "SuspendThread" ( _
    ByVal hThread As Long) As Long

    Private Declare Function PDevam Lib "kernel32" Alias "ResumeThread" ( _
    ByVal hThread As Long) As Long

    Private Declare Function PSonlandir Lib "kernel32" Alias "TerminateThread" ( _
    ByVal hThread As Long, _
    ByVal dwExitCode As Long) As Long

    Dim ParcacikId As Long

    Private Sub Command1_Click()
    ParcacikId = POlustur(ByVal 0&, ByVal 0&, AddressOf Parcacik, ByVal 0&, 0&, &O0)
    End Sub

    Private Sub Command2_Click()
    PSonlandir ParcacikId, 0&
    End Sub

    Private Sub Command3_Click()
    PDuraklat ParcacikId
    End Sub

    Private Sub Command4_Click()
    PDevam ParcacikId
    End Sub

    'Yeni thread bir modül içine yazılmalı. Çünkü AddressOf sadece
    'modül içerisindeki fonksiyonların adreslerini döndürebilir...
    Public Sub Parcacik()
    Do
    Form1.Text1.Text = Val(Form1.Text1.Text) + 1
    Loop
    End Sub
    Visual Basic.Net
    .Netin Threads kütüphanesi, thread yaratmak ve yönetmek için kendi içinde fonksiyonlar bulundurur. Ek olarak ortak kaynakları paylaşan parçacıkların yönetimini sağlamak için mutex ve semafor kullanımına da olanak tanıyan fonksiyonlar da barındırır. Bu kütüphanenin fonksiyonları sayesinde program birden fazla koldan hiçbir problemle karşılaşılmadan etkin bir şekilde çalışmasını sürdürür:
    Imports System.Threading
    Module Module1
    Sub Main()
    Dim Parcacik As New Thread(AddressOf YeniThread)
    Parcacik.Start()
    Thread.Sleep(3000) 'Biraz bekleyeyim, parçacık çalışsın sonra sonlanırım
    Console.WriteLine("Ben ana parçacığım, sonlanıyorum...")
    End Sub

    Sub YeniThread()
    Console.WriteLine("Ben yeni parçacığım ve işim saymak")
    Dim i As Integer
    For i = 1 To 10
    Thread.Sleep(1000)
    Console.WriteLine("Yeni Parçacık: " & i.ToString)
    Next i
    End Sub
    End Module
    Threadlerden Ana Thread Tarafından Oluşturulan Nesnelere Erişim
    Thread kütüphanesini yeni kullanmaya başlayanların karşılaşacağı ilk problem muhtemelen threadlerden ana thread içerisindeki nesnelerin değişkenlerini değişterememek olur. Problem, görevli(Delegate) metodlar ve invoke fonksiyonu kullanarak çözülür. Görevli metodlar C++ dilinde fonksiyonlara işaret eden işaretçilere benzetilebilir.
    Delegate Sub GorevliFonk(ByVal nesne As Object, ByVal deger As String)
    Private Sub Yaz(ByVal nesne As Object, ByVal deger As String)
    nesne.Text = deger
    End Sub

    Private Sub YeniThread()
    '...işlemler...
    'Text1Box1.Text = "AtasoyWeb" --> Hata verir
    'Invoke(GorevliFonksiyon(YurutmekleGorevliOlduğuFonksiyonunAdresi),Argümanlar)
    Invoke(New GorevliFonk(AddressOf Yaz), TextBox1, "AtasoyWeb")
    '...işlemler...
    End Sub
    Threadler Ve Ortak Kaynak Kullanımı
    Zor kısmını sona bıraktım, şimdi gelelim asıl meselemize... Parçacıklar aynı anda aynı kaynağa erişmek isteyebilirler. Bu durum kontrol altına alınmazsa problemlerle karşılaşılır. Aşağıdaki örnekte farklı iki thread aynı değişken üzerinde çalıştığından, program her çalıştırıldığında TextBox3 içerisinde değişik sonuçlar elde edilir. Eğer aynı değişkene erişim problem yaratmasaydı, her iki thread Sayi değişkenini 100000er defa arttırdığı için sonuç her seferinde 200000 olurdu. Ancak bir thread Sayi değerini okuyup arttırmış ve tam yerine yazacakken işletim sistemi işlemci kullanım hakkını diğer threade verebilir. Bu durumda 2. thread Sayi değerini okur, arttırır ve yazar ve bu işleme kendisine tanınan süre bitene kadar devam eder. Sıra tekrar 1. threade geldiğinde 1. thread kaldığı yerden devam eder ve biraz önce okuyup arttırdığı değeri yerine yazar. Bu yüzden 2. Threadin biraz önce kendisine verilen süre boyunca yaptığı işlerin tümü bir seferliğine boşa gitmiş olur. Sonuçta Sayi değişkeni her seferinde 200000den küçük veya 200000e eşit olabilen değişik değerlerde olur:
    'form içerisine 1 CommandButton ve 3 TextBox yerleştirin...
    Imports System.Threading
    Public Class Form1
    Private Sayi As Integer

    Delegate Sub GorevliFonk(ByVal nesne As Object, ByVal deger As String)
    Private Sub Yaz(ByVal nesne As Object, ByVal deger As String)
    nesne.Text = deger
    End Sub

    Private Sub Arttir()
    Sayi = Sayi + 1
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Sayi = 0
    Dim t1 As New Thread(AddressOf BenArttiracagim)
    Dim t2 As New Thread(AddressOf BenDeArttiracagim)
    t1.Start()
    t2.Start()
    End Sub

    Private Sub BenArttiracagim()
    Dim i As Integer
    For i = 1 To 100000 : Arttir() : Next
    Invoke(New GorevliFonk(AddressOf Yaz), TextBox1, Sayi.ToString) 'Thread1 işini bitirince
    Invoke(New GorevliFonk(AddressOf Yaz), TextBox3, Sayi.ToString) 'Son Durum
    End Sub

    Private Sub BenDeArttiracagim()
    Dim i As Integer
    For i = 1 To 100000 : Arttir() : Next
    Invoke(New GorevliFonk(AddressOf Yaz), TextBox2, Sayi.ToString) 'Thread2 işini bitirince
    Invoke(New GorevliFonk(AddressOf Yaz), TextBox3, Sayi.ToString) 'Son Durum
    End Sub
    End Class
    Mutex
    Yukarıda bahsetiğimiz ortak kaynak kullanımından kaynaklanan sorunları çözmek için mutexlerden faydalanılır. Bir thread, başka threadlerin de kullanabildiği bir kaynağa erişmeye çalıştığında, mutex değişkenini ayarlar. Bu atama işlemci tarafından kesinlikle kesilmez; yani thread mutexi tam yazacakken işletim sistemi sırayı başka bir threade vermez. (Mutexlerle ilgili işlemler gibi kesilmeden yapılan işlemlere atomik işlemler denir. Mutex ile ilgili işlemler gerçekte atomik olmadıkları halde, işletim sistemi tarafından atomik hale getirilir.) Böylece mutex ile korunan bölgeye erişmeye çalışan tüm threadler, orayı kullanan thread işini tamamlayana kadar bekletilir. Thread işini bitirdiğinde alanı serbest bıraktığını mutexe bildirir. Her sırası geldiğinde bu alana girmeye çalışan threadlerden ilk sırası gelen tekrar bölgeye girer ve mutex ile bölgeyi tekrar kilitler. Yukarıda verdiğim örnekte, bir mutex tanımlanır ve Arttir subı aşağıdaki gibi değiştirilirse Sayi değişkeninin son değerinin olması gerektiği gibi her seferinde 200000e eşit olduğu gözlenebilir:
    Private m1 As New Mutex
    Private Sub Arttir()
    m1.WaitOne() 'Mutex tüm threadleri bekletsin
    Sayi = Sayi + 1
    m1.ReleaseMutex() 'Mutexe bu korumalı alanı bıraktığını bildir
    End Sub
    Semafor (Semaphore)
    Semaforların amacı mutexlerin amacı ile aynıdır. Semaforlar mutexlerden farklı olarak birden fazla threadin aynı bölgeye girmesine izin verebilir. Mutexler semaforların iki durumlu özel halleri olarak düşünülebilir. Mutexler korudukları bölgeye sadece 1 threadin girmesine müsade ederken, semaforlar korumalı bölgeye giren thread sayısını belli bir değerle sınırlamak için kullanılır... Semaforun korumalı alan için izin verdiği thread sayısına yazının geri kalan kısmında kontenjan diyelim (bazen kavramları karşılayacak kelime bulmakta zorlanıyorum):
    Imports System.Threading
    Module Module1
    Private s1 As Semaphore

    Sub Main()
    s1 = New Semaphore(0, 2) ' Semaphore(BaşlangıçtakiBoşKontenjan,ToplamKontenjan)
    For i As Integer = 1 To 4
    Dim p As New Thread(AddressOf Parcacik)
    p.Start(i)
    Next i
    Thread.Sleep(2000)
    Console.WriteLine("Semaforda 2 yer ayrıldı")
    s1.Release(2) ' ana thread iki kişilik kontenjan ayırıyor
    End Sub

    Private Sub Parcacik(ByVal numaram As Integer)
    Console.WriteLine(numaram & ". thread: Başladım, semafor beni bekletiyor...")
    s1.WaitOne() ' İçerde bulunan haricindeki threadleri beklet
    Console.WriteLine(numaram & ". thread: alana girdim...")
    Thread.Sleep(4000) 'Thread zaman alan bir iş yapıyor...
    Console.WriteLine(numaram & ". thread: alanı bırakıyorum...")
    s1.Release()
    Thread.CurrentThread.Abort()
    End Sub
    End Module
    Yukarıdaki örneğin çıktısı:
    1. thread: Başladım, semafor beni bekletiyor...
    2. thread: Başladım, semafor beni bekletiyor...
    3. thread: Başladım, semafor beni bekletiyor...
    4. thread: Başladım, semafor beni bekletiyor...
    Semaforda 2 yer ayrıldı
    4. thread: alana girdim...
    2. thread: alana girdim...
    4. thread: alanı bırakıyorum...
    1. thread: alana girdim...
    2. thread: alanı bırakıyorum...
    3. thread: alana girdim...
    1. thread: alanı bırakıyorum...
    3. thread: alanı bırakıyorum...
    Yukarıdaki örnekte bölgeye, işlemci kullanım hakkını alan ilk iki thread girebilir. Bu yüzden threadler farklı sıralarda bölgeye girip sonlanabilirler. Yani çıktı her zaman yukarıdaki gibi olmayabilir.

    Threadler Arası Veri İletişimi
    Son olarak kısaca threadler arası iletişimden bahsedelim. Aynı işlem için çalışan threadler arasında ortak değişken kullanımı ile veri paylaşımı gerçekleştirilebilir. Böylece farklı threadler birbirlerinden farklı işlerle uğraşırken birbirleri ile iletişim halinde olabilirler... Örneğin bir threadin bir başkasının bittiğinden haberdar olması gerkesin. Thread tam sonlanacakken bir değişkene atama yaparak sonlandığını haber bekleyen threade bildirebilir. Haberi alacak olan thread sleep fonksiyonu yardımyla belli aralıklarla kendisine haber taşıyacak değişkenin içeriğini kontrol edebilir...

    Kaynak




  • Ajax dene olmadı thread sorgu secenekleri için bolca ornek var nette onlara bak derim.
  • Aslında olay şu :
    Programın görselliğini yöneten (GUI) objelere bir thread yönetiyor. Ve sen başka bir thread kullanarak bu GUI'ye müdahele etmek istediğinde bu olay GUI'yi yöneten thread'in hoşuna gitmiyor ve kendisine ait olan objelere dokunmana izin vermiyor. Aslında aldığın hatayı .NET'in göz ardı edebilmesi için bir ayar var ama tavsiye edilen bir durum değil. Sonuç itibari ile GUI'yi yöneten thread ile anlaşman için Delegate fonksiyon (GUI'de herhangi bir objenin değerini değiştiren bir fonksiyon) yazman lazım.
  • Yapay Zeka’dan İlgili Konular
    Daha Fazla Göster
    
Sayfa: 1
- x
Bildirim
mesajınız kopyalandı (ctrl+v) yapıştırmak istediğiniz yere yapıştırabilirsiniz.