نوشته شده توسط
s3rv3r
سلام دوستان من یه فانکشن نوشتم
private void Get_Data_Thread(int id,int lendata)
{
add_deligage_textbox(lendata);
}
فراخوانی با ترد هم به صورت زیر هستش
for(int dbid=0;dbid<40;dbid++)
Thread thwork = new Thread(delegate()
{
Get_Data_Thread(dbid, lendbgeted);
});
thwork.start();
Thread.sleep(500);
}
حالا وقتی وقتی اجرا میکنم انتظار دارم که اعداد 1 تا 40 به ترتیب به تکست باک اضافه بشن
ولی این اتفاق نمیفته 40 بار داده به تکست باکس اضافه میشه ولی تکراری داخلش هست به این صورت مثلا و حالا تصادفی عوض میشه اعداد
انگار که داده قبلی رو پاس میده.
1
2
3
4
5
6
7
7
9
10
11
12
12
13
.
.
.
ممنون میشم یکی کمکم کنه
با سلام.
اولا اگر 40 thread به صورت همزمان در حال اجرا باشند هیچ تضمینی نیست که به ترتیبی که ساخته شدند اجرا شوند و ممکن است کار اجرای thread بعی زودتر از thread قبل از خودش کامل شود.
از طرفی استفاده از lambda به عنوان سازنده thread ممکن است نتیجه های پیش بینی نشده ای در بر داشته باشد، به دلیل اینکه مقدار متغیری که در lambda از آن استفاده می کنید، مقداری نیست که این متغیر زمان ساخت lambda در خود دارد بلکه مقدار این متغیر در زمان اجرای lambda محاسبه می شود.
مثلا اگر در حلقه ای 40 عبارت lambda بنویسیم و از شمارنده حلقه در این عبارات استفاده کرده و بعد از اتمام حلقه عبارات را اجرا کنیم مقدار متغیر استفاده شده، مقداری است که در حال حاضر در آن است.
امیدوارم مثال زیر به طور کامل گویای مساله باشد:
//in the name of god
//صل الله علی محمد و آله
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
////////////test1
Console.WriteLine("test1");
for (int i = 0; i < 40; i++)
{
Thread thread2 = new Thread(delegate()
{
Console.WriteLine(i);
});
thread2.Start();
}
Thread.Sleep(100);
Console.WriteLine(new string('-',80));
//////////////test2
Console.WriteLine("test2");
for (int j = 0; j < 40; j++)
{
Thread thread3 = new Thread(() => Console.WriteLine(j));
thread3.Start();
}
Thread.Sleep(100);
Console.WriteLine(new string('-',80));
/////////////test3
Console.WriteLine("test3");
List<Thread> threads = new List<Thread>();
for (int i = 0; i < 40; i++)
{
threads.Add(new Thread(() => Console.WriteLine(i)));
}
threads.ForEach((thread4) => thread4.Start());
Console.WriteLine(new string('-', 80));
//////////////test4
Console.WriteLine("test4");
threads.Clear();
for (int j = 0; j < 40; j++)
{
Thread thread5=new Thread((ParameterizedThreadStart)Console.WriteLine );
thread5.Start(j);
}
Console.WriteLine(new string('-',80));
//////////////test5
for(int i=0;i<40;i++)
{
Thread thread6=new Thread((ParameterizedThreadStart)Console.WriteLine );
thread6.Start(i);
Thread.Sleep(25);
}
}
}
}
نتیجه:
test1
0
1
2
3
4
6
6
8
8
10
10
12
12
14
14
16
16
18
18
20
20
22
22
24
24
26
26
28
28
30
30
31
32
33
34
36
36
38
38
39
--------------------------------------------------------------------------------
test2
1
1
2
4
3
6
6
8
10
9
12
7
11
13
14
15
16
17
18
19
21
20
22
23
24
25
27
27
28
29
30
31
32
34
35
36
36
38
38
40
--------------------------------------------------------------------------------
test3
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
40
--------------------------------------------------------------------------------
test4
0
1
2
3
4
5
6
7
8
9
10
12
11
13
15
14
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
32
31
33
34
35
36
37
39
38
--------------------------------------------------------------------------------
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Press any key to continue . . .
مثالهای test1 و test2 که در واقع دقیقا یکی هستند و خروجی ممکن است نا مرتب و تکراری باشد.
در test3همانطور که می بینید چون threadها بعد از حلقه اجرا می شوند، در هر 40 thread عدد 40 (عددی که در زمان اجرای thread در i است و نه در زمان ساخت آن) نمایش داده می شود.
در test4 مقادیر متغیرها در زمان ساخت thread مورد استفاده قرار میگیرد ولی ممکن است یک thread زودتر از thread قبلی خود اجرا شود و اعداد کاملا به ترتیب نباشند که برای حل این موضوع بهتر است از یک thread برای همه موارد استفاده شود و یا اینکه بعد از اجرای هر htread به thread اصلی کمی استراحت داده شود تا thread قبلی کاملا شروعبه کار کند.