Posted by: bokhoo | September 4, 2009

C#: Thread & MethodInvoker

Сайн байна уу залуусаа.

Өмнө нь Thread гээд л жижиг post бичиж байсан даа. Тэгвэл энэ удаад жаахан дэлгэрүүлье гэж бодлоо.

Хүмүүс Tread – ийн тухай онол ярьвал ингэж ярих байх.
Чиний хийж байгаа програм бол аав процесс, Thread бол хүү процесс. Аав хэдэн ч хүүтэй байж болно. Аав байхгүй бол хүү байхгүй гээд л ярих байсан байх … :P

C# дээр бол :
using System.Threading;

private void Thread_Job()
{
this.Button1.Text = “товч”;
}

ThreadStart ts = new ThreadStart(Thread_Job);
Thread t = new Thread(ts);
t.Start();

// Thread_Job – гэх функцыг ажиллуулахад бол ингээд л боллоо. Тухайн Thread_Job функц ямарч асуудалгүй чиний програмыг гацаахгүй ажиллах ба функц дуусахад Thread зогсоно. Гэвч нэг асуудал гарч ирсэн. Юу вэ гэвэл: Thread_Job функ дотороо юу ч бичсэн болох боловч үндсэн Main Thread рүүгээ хандах боломжгүй болчихсон. хамгийн энгийнээр л гэхэд this.Button1.Text = “товч”; гэх код ажиллахгүй. Үүнийг шийдхийн тулд MethodInvoker – ийг ашигладаг юм байна. Жишээ нь:

private void Thread_Job()
{
this.Invoke((MethodInvoker)delegate() { this.Button1.Text = “товч”; });
}

Гэвэл харин ажиллана.

Тэгвэл харин:

private void TextChanger()
{
this.Button1.Text = “товч”;
}

private void Thread_Job()
{
Invoke((MethodInvoker)delegate() { this.Button1.Text = “товч”; });
TextChanger();
}

гэж бичвэл бас л ажиллахгүй бөгөөд

private void Thread_Job()
{
this.Invoke((MethodInvoker)delegate() { this.Button1.Text = “товч”; });

Invoke(new MethodInvoker(TextChanger));

//Өөрөөр

MethodInvoker tch = new MethodInvoker(TextChanger);
Invoke(tch);
}

гэвэл харин ажиллана.

Анхааруулхад:Invoke ашиглаж байх үед Thread.Abort() хийж алдаа зааж байна лээ шүү. Тухайн функ дуусахад Thread аяндаа зогсоно.
Хэрэг болох болтугай… амжилт… :P


Responses

  1. Дээр нь нэмээд хэлэхэд, өөр thread дээрээс яагаад main thread рүү хандаж болдоггүй юм бэ гэвэл windows program-ууд нь message loop ашиглан ажилдаг юм. Програм эхлэх үед UI thread буюу гол thread нь нэг message queue үүсгэдэг ба үүнийг TLS буюу thread local storage ашиглан өөртөө хамаатуулдаг юм. Өөр thread дээр this.button1.Text = “30″; гэж өгөх үед тухайн button1 контрол дотоод өгөгдлөө өөрчлөх боловч шинээр өөрийгөө зурах хүсэлтээ message болгон тухайн thread-ийн message queue рүү post хийдэг юм. Гэтэл шинэ thread ямар ч message queue, loop байхгүй тул тухайн контрол гацсан юм шиг болдог. Мөн .NET орчинд тухайн контрол өөр thread – ээс дуудагдвал алдаа өгдөг болсон байх шиг байна лээ. Invoke нь харин тухайн функцыг тухайн контрол үүссэн тэр thread дээр дууддаг юм. Гэхдээ үүнийг дуудахдаа контролын HandleCreated нь true байх ёстойг шалгах хэрэгтэй үгүй бол олоход хэцүү алдаа гарж, гацдаг юм шүү … Хэхэ хэтэрхий их юм биччих үү дээ …

  2. nice онолын үүднээс ярьж байна. чико tnks

  3. ene post-n buruu bichsen zuiliig joshua zov bolgoj ogson bn, good.
    UI threadin xuvid ingej invoke xiij oor thread-s oorchilxoos gadna, Control.CheckForIllegalCrossThreadCalls = false; bolgoj bolno, xaraad l oilgogdoj bgaa biz dee. ingesen toxioldold thread dotoros UI object ruu shuud xandaj bolno.

  4. харин тийм, баярлалаа та 2т


Leave a response

Your response:

Categories