Tutorial C#login
Tutorial C#
pengarang:php.cn  masa kemas kini:2022-04-11 14:06:23

C# multithreading



Benang ditakrifkan sebagai laluan pelaksanaan program. Setiap utas mentakrifkan aliran kawalan yang unik. Jika aplikasi anda melibatkan operasi yang kompleks dan memakan masa, selalunya berfaedah untuk menyediakan laluan pelaksanaan benang yang berbeza, setiap utas melaksanakan kerja tertentu.

Benang ialah proses ringan. Contoh biasa penggunaan benang ialah pelaksanaan pengaturcaraan selari dalam sistem pengendalian moden. Menggunakan benang menjimatkan kitaran CPU yang terbuang sambil meningkatkan kecekapan aplikasi.

Atur cara yang telah kami tulis setakat ini ialah satu utas yang berjalan sebagai satu proses bagi contoh yang sedang berjalan bagi aplikasi. Walau bagaimanapun, subaplikasi ini hanya boleh melaksanakan satu tugas pada satu masa. Untuk melaksanakan pelbagai tugas secara serentak, ia boleh dibahagikan kepada benang yang lebih kecil.

Kitaran Hayat Benang

Kitaran hayat benang bermula apabila objek Sistem.Threading.Kelas Benang dicipta dan tamat apabila benang ditamatkan atau menyelesaikan pelaksanaan.

Pelbagai keadaan dalam kitaran hayat benang disenaraikan di bawah:

  • Keadaan tidak dimulakan : Apabila contoh benang dibuat tetapi kaedah Mula mempunyai bukan Syarat apabila dipanggil.

  • Keadaan sedia : Keadaan apabila benang sedia untuk dijalankan dan menunggu kitaran CPU.

  • Status tidak boleh beroperasi: Urutan tidak boleh beroperasi dalam situasi berikut:


    • Kaedah tidur telah dipanggil

    • Kaedah tunggu telah dipanggil

    • Disekat oleh operasi I/O

  • Status kematian: Keadaan apabila urutan telah menyelesaikan pelaksanaan atau telah ditamatkan.

Main Thread

Dalam C#, kelas System.Threading.Thread digunakan untuk kerja thread. Ia membenarkan penciptaan dan akses benang individu dalam aplikasi berbilang benang. Benang pertama yang akan dilaksanakan dalam proses dipanggil benang utama.

Apabila program C# mula dilaksanakan, utas utama dibuat secara automatik. Benang yang dibuat menggunakan kelas Benang dipanggil oleh urutan anak urutan utama. Anda boleh mengakses utas menggunakan harta CurrentThread kelas Thread.

Atur cara berikut menunjukkan pelaksanaan utas utama:

using System;
using System.Threading;

namespace MultithreadingApplication
{
    class MainThreadProgram
    {
        static void Main(string[] args)
        {
            Thread th = Thread.CurrentThread;
            th.Name = "MainThread";
            Console.WriteLine("This is {0}", th.Name);
            Console.ReadKey();
        }
    }
}

Apabila kod di atas disusun dan dilaksanakan, ia akan menghasilkan keputusan berikut:

This is MainThread

Kelas utas biasanya digunakan Atribut dan kaedah

Jadual berikut menyenaraikan beberapa atribut yang biasa digunakan bagi kelas Thread:

属性描述
CurrentContext获取线程正在其中执行的当前上下文。
CurrentCulture获取或设置当前线程的区域性。
CurrentPrinciple获取或设置线程的当前负责人(对基于角色的安全性而言)。
CurrentThread获取当前正在运行的线程。
CurrentUICulture获取或设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源。
ExecutionContext获取一个 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息。
IsAlive获取一个值,该值指示当前线程的执行状态。
IsBackground获取或设置一个值,该值指示某个线程是否为后台线程。
IsThreadPoolThread获取一个值,该值指示线程是否属于托管线程池。
ManagedThreadId获取当前托管线程的唯一标识符。
Name获取或设置线程的名称。
Priority获取或设置一个值,该值指示线程的调度优先级。
ThreadState获取一个值,该值包含当前线程的状态。

Jadual berikut menyenaraikan beberapa kaedah yang biasa digunakan bagi kelas Benang:

Nombor siriNama kaedah & huraian
1kekosongan awam Batalkan( )
Melemparkan ThreadAbortException pada utas yang memanggil kaedah ini untuk memulakan proses menamatkan utas ini. Memanggil kaedah ini biasanya menamatkan benang.
2LocalDataStoreSlot statik awam AllocateDataSlot()
Peruntukkan slot data yang tidak dinamakan pada semua urutan. Untuk prestasi yang lebih baik, gunakan medan yang ditandakan dengan atribut ThreadStaticAttribute sebaliknya.
3SlotDataStoreSlot statik awam AllocateNamedDataSlot( nama rentetan)
Peruntukkan slot data bernama pada semua urutan. Untuk prestasi yang lebih baik, gunakan medan yang ditandakan dengan atribut ThreadStaticAttribute sebaliknya.
4public static void BeginCriticalRegion()
Memberitahu hos bahawa pelaksanaan akan memasuki kawasan kod di mana urutan tamat Atau kesan pengecualian yang tidak dikendalikan boleh membahayakan tugas lain dalam domain aplikasi.
5public static void BeginThreadAffinity()
Memberitahu kod diurus hos bahawa ia akan melaksanakan urutan yang bergantung pada identiti urutan sistem pengendalian fizikal semasa.
6public static void EndCriticalRegion()
Memberitahu hos bahawa pelaksanaan akan memasuki kawasan kod di mana urutan tamat Atau pengecualian yang tidak dikendalikan hanya menjejaskan tugas semasa.
7public static void EndThreadAffinity()
Memberitahu hos bahawa kod terurus telah selesai dilaksanakan bergantung pada identiti semasa arahan benang sistem pengendalian fizikal.
8public static void FreeNamedDataSlot(string name)
Menghapuskan perkaitan antara nama dan slot untuk semua thread dalam proses . Untuk prestasi yang lebih baik, gunakan medan yang ditandakan dengan atribut ThreadStaticAttribute sebaliknya.
9Objek statik awam GetData( Slot LocalDataStoreSlot )
Mengambil nilai daripada slot yang ditentukan pada utas semasa dalam domain semasa utas semasa. Untuk prestasi yang lebih baik, gunakan medan yang ditandakan dengan atribut ThreadStaticAttribute sebaliknya.
10AppDomain statik awam GetDomain()
Mengembalikan domain semasa di mana urutan semasa sedang dijalankan.
11AppDomain statik awam GetDomainID()
Mengembalikan pengecam domain aplikasi yang unik.
12LocalDataStoreSlot statik awam GetNamedDataSlot( nama rentetan )
Cari slot data bernama. Untuk prestasi yang lebih baik, gunakan medan yang ditandakan dengan atribut ThreadStaticAttribute sebaliknya.
13public void Interrupt()
Ganggu urutan dalam keadaan WaitSleepJoin thread.
14kekosongan awam Sertai()
Menyekat urutan panggilan sehingga salah satu utas ditamatkan sementara pemprosesan pam mesej COM dan SendMessage standard diteruskan. Terdapat kelebihan yang berbeza bagi kaedah ini.
15public static void MemoryBarrier()
Segerakkan akses memori seperti berikut: Pemproses melaksanakan utas semasa Apabila arahan disusun semula , akses memori selepas panggilan MemoryBarrier tidak boleh dilakukan dahulu, dan kemudian akses memori sebelum panggilan MemoryBarrier dilakukan.
16public static void ResetAbort()
Batalkan Batal yang diminta untuk urutan semasa.
17setData kekosongan statik awam( Slot LocalDataStoreSlot, Data objek )
Tetapkan data dalam slot yang ditentukan untuk domain semasa thread ini pada thread yang sedang dijalankan. Untuk prestasi yang lebih baik, gunakan medan yang ditandakan dengan atribut ThreadStaticAttribute sebaliknya.
18public void Start()
Mulakan urutan.
19kekosongan statik awam Tidur( int milisaatTamat masa )
Biarkan benang itu berhenti seketika.
20kekosongan statik awam SpinWait( lelaran int )
menyebabkan urutan menunggu untuk jumlah masa yang ditentukan oleh parameter lelaran.
21bait statik awam VolatileRead( alamat bait ref )
kembar statik awam VolatileRead( ref alamat berganda )
int statik awam VolatileRead( alamat int ref )
Objek statik awam VolatileRead( alamat refObject )

Baca nilai medan. Nilai ini ialah nilai terbaharu yang ditulis oleh mana-mana pemproses komputer, tanpa mengira bilangan pemproses atau keadaan cache pemproses. Terdapat kelebihan yang berbeza bagi kaedah ini. Hanya beberapa borang diberikan di sini.
22void statik awam VolatileWrite( alamat bait ref, nilai bait )
kekosongan statik awam VolatileWrite( rujuk alamat ganda, nilai berganda )
kekosongan statik awam VolatileWrite( alamat int ref, nilai int )
kekosongan statik awam VolatileWrite( alamat objek ref, Nilai objek )

Menulis nilai pada medan dengan serta-merta, menjadikan nilai itu kelihatan kepada semua pemproses dalam komputer. Terdapat kelebihan yang berbeza bagi kaedah ini. Hanya beberapa borang diberikan di sini.
23public static bool Yield()
Menyebabkan utas panggilan melaksanakan urutan lain yang sedia untuk dijalankan pada arus pemproses . Sistem pengendalian memilih utas yang hendak dilaksanakan.

Mencipta Benang

Benang dicipta dengan melanjutkan kelas Benang. Kelas Thread lanjutan memanggil kaedah Start() untuk memulakan pelaksanaan thread anak.

Atur cara berikut menunjukkan konsep ini:

using System;
using System.Threading;

namespace MultithreadingApplication
{
    class ThreadCreationProgram
    {
        public static void CallToChildThread()
        {
            Console.WriteLine("Child thread starts");
        }
        
        static void Main(string[] args)
        {
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
            Console.ReadKey();
        }
    }
}

Apabila kod di atas disusun dan dilaksanakan, ia menghasilkan keputusan berikut:

In Main: Creating the Child thread
Child thread starts

Mengurus Benang

Kelas Thread menyediakan pelbagai kaedah untuk menguruskan benang.

Contoh berikut menunjukkan penggunaan kaedah sleep(), yang digunakan untuk menjeda urutan pada masa tertentu.

using System;
using System.Threading;

namespace MultithreadingApplication
{
    class ThreadCreationProgram
    {
        public static void CallToChildThread()
        {
            Console.WriteLine("Child thread starts");
            // 线程暂停 5000 毫秒
            int sleepfor = 5000; 
            Console.WriteLine("Child Thread Paused for {0} seconds", 
                              sleepfor / 1000);
            Thread.Sleep(sleepfor);
            Console.WriteLine("Child thread resumes");
        }
        
        static void Main(string[] args)
        {
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
            Console.ReadKey();
        }
    }
}

Apabila kod di atas disusun dan dilaksanakan, ia akan menghasilkan keputusan berikut:

In Main: Creating the Child thread
Child thread starts
Child Thread Paused for 5 seconds
Child thread resumes

Memusnahkan benang

Abort() kaedah ialah digunakan Musnahkan benang.

Hentikan benang pada masa jalan dengan melontar threadabortexception. Pengecualian ini tidak boleh ditangkap Jika terdapat blok akhirnya, kawalan akan dihantar ke blok akhirnya.

Atur cara berikut menggambarkan ini:

using System;
using System.Threading;

namespace MultithreadingApplication
{
    class ThreadCreationProgram
    {
        public static void CallToChildThread()
        {
            try
            {

                Console.WriteLine("Child thread starts");
                // 计数到 10
                for (int counter = 0; counter <= 10; counter++)
                {
                    Thread.Sleep(500);
                    Console.WriteLine(counter);
                }
                Console.WriteLine("Child Thread Completed");

            }
            catch (ThreadAbortException e)
            {
                Console.WriteLine("Thread Abort Exception");
            }
            finally
            {
                Console.WriteLine("Couldn't catch the Thread Exception");
            }

        }
        
        static void Main(string[] args)
        {
            ThreadStart childref = new ThreadStart(CallToChildThread);
            Console.WriteLine("In Main: Creating the Child thread");
            Thread childThread = new Thread(childref);
            childThread.Start();
            // 停止主线程一段时间
            Thread.Sleep(2000);
            // 现在中止子线程
            Console.WriteLine("In Main: Aborting the Child thread");
            childThread.Abort();
            Console.ReadKey();
        }
    }
}

Apabila kod di atas disusun dan dilaksanakan, ia menghasilkan keputusan berikut:

In Main: Creating the Child thread
Child thread starts
0
1
2
In Main: Aborting the Child thread
Thread Abort Exception
Couldn't catch the Thread Exception

Laman web PHP Cina