PDA

View Full Version : سوال: ارسال تابع با پارامتر به Thread



ahmad_lovely
شنبه 31 اردیبهشت 1390, 00:37 صبح
سلام
من می خوام یه تابع رو که دوتا پارامتر string داره رو به thread پاس بدم ولی خطا میده !
از دوستان کسی هست که بتونه کمکم کنه؟
ممنون

Amir Oveisi
شنبه 31 اردیبهشت 1390, 10:55 صبح
از چه روشی برای این کار استفاده می کنید؟ با چه خطایی مواجه میشید؟ انتظار ندارید که بدون توضیح دادن این مسائل کسی بتونه مشکل شما رو حدس! بزنه؟
لطفا با جزئیات بیشتری سوالتون رو مطرح بفرمایید :)
موفق باشید

ahmad_lovely
شنبه 31 اردیبهشت 1390, 11:34 صبح
ببینید من می خوام مثلا چنین تابعی رو که به صورت بازگشتی هست به thread پاس بدم، چطوری می تونم این کار رو بکنم ؟
من با thread start این تابع رو پاس دادم ولی چون پارامتر داره خطا میده !




private void f1(string a1, string a2)
{
a1=a1+"a";
a2=a2+"b";
f1(a1,a2);
}




اصلا می خوام بدونم یه تابع که چند پارامتر از نوع مختلف داره رو چطوری میتونم به thread پاس بدم ؟
ممنون

mehranmsba
شنبه 31 اردیبهشت 1390, 12:44 عصر
شما تنها چیزی که می تونید به یک Thread متصل کنید یک Object است که هر نوع متغیر و کلاسی را قبول می کند پس کافی ThreadStart خود را تبدیل به ParameterizedThreadStart که خودش داره می گه پارامتر می گیره کنید:

System.Threading.Thread p1;
private void Runp1(object A) {

MessageBox.Show(A.ToString());
}

private void button2_Click(object sender, EventArgs e)
{
p1 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Runp1));
p1.Start("Salam");



}


خوب حالا شما باید متدت رو تغییر بدی به طوری که یک ورودی Object داشته باشه و به جای پارامتر ها یک آرایه رشته برگردونی این طوری:

System.Threading.Thread p1;
private void Runp1(object A) {
string[] parameter = (string[])A;
MessageBox.Show(parameter[0], parameter[1]);

}

private void button2_Click(object sender, EventArgs e)
{
p1 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Runp1));
string[] s = new string[2];
s[0] = "Salam";
s[1] = "khoobi";
p1.Start(s);



}


حالا اگر ممکنه که شما چندین پارامتر داشه باشید و نتونید OverLoad کنید می بایست:

private void Runp1(object A) {
if(A.GetType()==typeof(string[])){
string[] parameter = (string[])A;
MessageBox.Show(parameter[0], parameter[1]);
}
if(A.GetType()==typeof(int[])){
MessageBox.Show((((int[])(A))[0] + ((int[])(A))[1]).ToString());

}
}


private void button2_Click(object sender, EventArgs e)
{
p1 = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Runp1));
string[] s = new string[2];
int[] i = new int[2];
s[0] = "Salam";
s[1] = "khoobi";
i[0] = 10;
i[1] = 20;
//p1.Start(s);
p1.Start(i);


}

حالا با تشخیص ابنکه چه پارامتری اومده نسبت به اون واکنش نشون می دهیم.

یک راه دیگر هم وجود داره که شما دقیقا متد خود را با هر نوع پارامتری که هست منتقل کنید (در واقع یک کلک است!)

System.Threading.Thread p1;
private void Runp1(string A,string B)
{
MessageBox.Show(A,B);

}


private void button2_Click(object sender, EventArgs e)
{

System.Threading.ThreadStart Runners = delegate { Runp1("SSS","Msba"); };
p1 = new System.Threading.Thread(Runners);
p1.Start();

}

در برنامه بالا یک وکیل از متد خود می گیریم با مقدار پارامتری که می خواهیم (هر چی ) بعدش می دهیم به یک Thread که زحمتش رو بکشه.

موفق باشید.

tooraj_azizi_1035
شنبه 31 اردیبهشت 1390, 14:26 عصر
سلام،
این لینک: http://msdn.microsoft.com/en-us/library/aa645740(v=vs.71).aspx

ahmad_lovely
شنبه 31 اردیبهشت 1390, 20:35 عصر
سلام، میشه در مورد کار delegate یه توضیحی بدهید، مثلا بگید این کد چه کاری انحام می دهد که باعث می شود تابع با پارامتر رو به اون بدهیم
همچنین در چه مواقعی این متد کاربرد دارد؟
در ضمن یه سوال دیگه هم داشتم اینکه چطوری میشه با استفاده از کنترل progress bar میزان کپی یه فولدر رو نشان داد؟
ممنون

ahmad_lovely
یک شنبه 01 خرداد 1390, 10:28 صبح
من وقتی این تابع رو به ترد پاس میدم وقتی به خط اول میرسه چنین خطایی میده !
cross-thread operation not valid. control 'treeview' accessed from a thread other than the thread it was created on.

این تابع رو به ترد پاس دادم :

node.Nodes.Clear();
DirectoryInfo d = new DirectoryInfo(node.FullPath.Substring(12));
foreach (DirectoryInfo dir in d.GetDirectories())
{
TreeNode node1 = new TreeNode();
node1.Text = dir.Name;
node1.Nodes.Add("");
node.Nodes.Add(node1);
}

Amir Oveisi
دوشنبه 02 خرداد 1390, 10:00 صبح
شما از یک thread نمیتونید به object های تولید شده توسط یک thread دیگه دسترسی داشته باشید و این exception هم به همین دلیل رخ داده.
برای اینکه بتونین این کار رو انجام بدید باید یک سری تغییراتی اعمال کنید:

Thread t = new Thread(new ThreadStart(this.update));
delegate void UpdateDelegate();
...
t.start();
...
void update()
{
if(node.InvokeRequired)
{
UpdateDelegate ud = new UpdateDelegate(this.update);
Invoke(ud);
}
else
{
//کارهای مورد نیازتون رو اینجا انجام بدید.
node.Nodes.Clear();
DirectoryInfo d = new DirectoryInfo(node.FullPath.Substring(12));
foreach (DirectoryInfo dir in d.GetDirectories())
{
TreeNode node1 = new TreeNode();
node1.Text = dir.Name;
node1.Nodes.Add("");
node.Nodes.Add(node1);
}
}
}

اطلاعات بیشتر در این مورد در سایت وجود داره، لطفا جستجو کنید.
موفق باشید

ahmad_lovely
دوشنبه 02 خرداد 1390, 11:33 صبح
سلام
اگر تابع من چنین پارامترهایی داشته باشه چه پارامتری به delegate بدم؟

public void CreateDesktop(ref TreeView tv, ref ImageList ImgLst)
{
}