PDA

View Full Version : سوال: thread برای متدهای غیر static



drsina
پنج شنبه 02 آبان 1392, 20:49 عصر
سلام !
یه نخ به صورت زیر نوشتم :

public static Thread nakh1 = new Thread(new ThreadStart(time));



و حالا یه متد دارم :

public void time()
{
int time = 0;

while (1 == 1)
{
System.Threading.Thread.Sleep(1000);
time++;
label1.Text = time.ToString();
}

}


حالا اررو میده :
A field initializer cannot reference the non-static field, method, or property

چه جوری میشه حلش کرد ؟!

esafb52
پنج شنبه 02 آبان 1392, 21:00 عصر
اون متد و اون متغیر رو هم اساتیک تعریف کن

drsina
پنج شنبه 02 آبان 1392, 21:04 عصر
مسئله ای با static تعریف کردن متغیر و مت ها نیست ، موضوع اینجاست ، که توویه یه متد استاتیک از
label1.Text = time.ToString();

نمیشه استفاده کرد .

pedram.11
جمعه 03 آبان 1392, 09:56 صبح
سلام !
یه نخ به صورت زیر نوشتم :

public static Thread nakh1 = new Thread(new ThreadStart(time));


حالا اررو میده :
A field initializer cannot reference the non-static field, method, or property

چه جوری میشه حلش کرد ؟!

سلام. اگه میخواید ترد رو به اینصورت تعریف کنید مشکلی نداره. اما برای انتساب باید داخل متد اینکارو انجام بدید، چون شما میخواید از یک فیلد static یک فیلد non-static رو معرفی کنید!برای حل به اینصورت بنویسید:
void StartTimer()
{
nakh1 = new Thread(new ThreadStart(time));
nakh1.Start();
}

درضمن یه نکته ای بگم که اگه کنترل label1 شما بصورت استاتیک نیست و اگه در یک نخ دیگه معرفی شده توی این متد شما به ارور InvalidOperationException برمیخورید و دلیلشم هیمنه که کنترل label در یک نخ دیگه تعریف شده و توی نخ جدی بهش دسترسی ندارید...

CsharpNevisi
جمعه 03 آبان 1392, 10:20 صبح
CheckForIllegalCrossThreadCalls = false;
Thread Th = new Thread(Rec);
Th.Start();
باید به تردت اجازه دسترسی به کامپوننت هارو بدی ...

FastCode
جمعه 03 آبان 1392, 11:00 صبح
CheckForIllegalCrossThreadCalls = false;
Thread Th = new Thread(Rec);
Th.Start();
باید به تردت اجازه دسترسی به کامپوننت هارو بدی ...
خیلی خوب بود اگر افرادی که پست میدادن میدونستن کدشون چه کاری انجام میده.
هر چیزی که بعضی وقتها کار نمیکنه نمیتونه خوب باشه.
به جای این از Control.Invoke استفاده کنید.

pedram.11
جمعه 03 آبان 1392, 11:15 صبح
خیلی خوب بود اگر افرادی که پست میدادن میدونستن کدشون چه کاری انجام میده.
هر چیزی که بعضی وقتها کار نمیکنه نمیتونه خوب باشه.
به جای این از Control.Invoke استفاده کنید.

والا منم از وجود همچین دستوری خبر نداشتم و همیشه برای انتقال به نخ اصلی از delegate استفاده میکردم و یا از همین کدی که شما میفرمایید.
با توجه به توضیحی که در مورد این نوشته:
Gets or sets a value indicating whether to catch calls on the wrong thread that access a control's System.Windows.Forms.Control.Handle property when an application is being debugged.
میگه که به فراخوانی کنترلها در نخ های اشتباه گیر بده یا نه. اما من تست کردم در نخ دیگه به کنترل دسترسی پیدا کرد! استفاده از این کد مشکل سازه آیا؟

CsharpNevisi
جمعه 03 آبان 1392, 11:18 صبح
خیلی خوب بود اگر افرادی که پست میدادن میدونستن کدشون چه کاری انجام میده.
هر چیزی که بعضی وقتها کار نمیکنه نمیتونه خوب باشه.
به جای این از Control.Invoke استفاده کنید.

مگه نمیگید اروره InvalidOperationException رو میده ؟؟؟؟؟؟؟
خب این اجازه دسترسی به کامپوننت های ترد اصلی برنامه رو میده !!!!!!!
اگه باورش اینقدر سخته نمونه کد بدم بهتر متوجه شید ... !!!!!!!

FastCode
جمعه 03 آبان 1392, 11:51 صبح
در واقع باور این سخته که شما فکر میکنید من نمیدونم راجع به چی صحبت میکنم.
برای اینکه ببینید چقدر بده میتونید جستوجو کنید:
CheckForIllegalCrossThreadCalls
یا DoEvents(نتیجه ای که دارن یکی هست.فقط CheckForIllegalCrossThreadCalls یک مقدار شدیدتره.)

CsharpNevisi
جمعه 03 آبان 1392, 11:59 صبح
تا حالا نشنیده بودم که CheckForIllegalCrossThreadCalls میتونه مظر باشه ... این سایت برای یادگیریه شمام جای استاد من .... !!!!!
میشه یه ذره از بدیاش بگید ؟؟؟؟

FastCode
جمعه 03 آبان 1392, 12:06 عصر
بدی هایی که داره اینه که مثلا وسط WM_DRAW شما متن یک کنترل رو آپدیت میکنید.
Background چاپ میشه.
سه خط اول متن چاپ میشه.
از خط چهارم بقیه متن دوم چاپ میشه.
این یک حالت بود که خطا نمیده.
مثال از این دست خیلی زیاده.
معمولا هم منجر به خطا میشه و کاملا هم غیر قابل پیشبینیه.

drsina
جمعه 03 آبان 1392, 13:08 عصر
سلام. اگه میخواید ترد رو به اینصورت تعریف کنید مشکلی نداره. اما برای انتساب باید داخل متد اینکارو انجام بدید، چون شما میخواید از یک فیلد static یک فیلد non-static رو معرفی کنید!برای حل به اینصورت بنویسید:
void StartTimer()
{
nakh1 = new Thread(new ThreadStart(time));
nakh1.Start();
}

درضمن یه نکته ای بگم که اگه کنترل label1 شما بصورت استاتیک نیست و اگه در یک نخ دیگه معرفی شده توی این متد شما به ارور InvalidOperationException برمیخورید و دلیلشم هیمنه که کنترل label در یک نخ دیگه تعریف شده و توی نخ جدی بهش دسترسی ندارید...


سلام !
ممنون از جوابت ، کاری که می خواستم ، حل شد .
ولی از لحاظ منطقی ، هیچ فرقی با کد اول من نداشت ، پس یعنی چی شد الان توو کد ، که دیگه ایراد نمیگره ؟! :متفکر:

pedram.11
جمعه 03 آبان 1392, 13:24 عصر
سلام !
ممنون از جوابت ، کاری که می خواستم ، حل شد .
ولی از لحاظ منطقی ، هیچ فرقی با کد اول من نداشت ، پس یعنی چی شد الان توو کد ، که دیگه ایراد نمیگره ؟! :متفکر:

خب شما دارید یک عبارت غیر استاتیک رو بصورت محلی به عبارت استاتیک انتساب میدید. میدونیم که عبارت های استاتیک به صورت ساکن و همیشگی در زمان اجرای برنامه وجود دارن در صورتی که عبارتهای غیر استاتیک ابتدا باید کلاس والدشون تعریف بشن. خب اینجا شما تردتون رو به صورت استاتیک تعریف کردید و درصورتی که بخواید یک مقدار غیر استاتیک اختصاص بدید کامپایلر بهتون اخطار میده، چون قبل از تعریف کلاس و متدهاشون این عبارت استاتیک تعریف شده هست اما عبارتهای غیر استاتیکی موجود در کلاس نه.