PDA

View Full Version : سوال: خطا در موازی سازی



elahe1393
شنبه 26 مهر 1393, 08:45 صبح
من تو برنامه ام از موازی سازی استفاده کردم در بخشی از کد از خط زیر استفاده کردم

this.BeginInvoke(new MethodInvoker(delegate{txtRecieveData.AppendText(s tr);}));

زمان اجرا با خطای زیر مواجه میشم مشکل چیه و چطور باید حلش کنم؟

'txtRecieveData.Text' threw an exception of type 'Microsoft.VisualStudio.Debugger.Runtime.CrossThre adMessagingException'

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

elyas_delshadnbe
شنبه 26 مهر 1393, 08:58 صبح
از طريق thread هايي كه خودت ميسازي نميتوني textbox رو تغيير بدي.بايد با استفاده از دستور invoke اين كار رو درون thread اصلي انجام بدي

elyas_delshadnbe
شنبه 26 مهر 1393, 09:02 صبح
به جاي اون دستور از اين دستور استفاده كن فك كنم مشكلت حل شه
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });

elyas_delshadnbe
شنبه 26 مهر 1393, 09:12 صبح
و يا كاملترش ميشه استفاده از اين تابع و پاس دادن هر مقداري به منظور نمايش در تكست باكس به اون


private void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
Txt_Result.Text += value + "\r\n";
}

elahe1393
شنبه 26 مهر 1393, 10:17 صبح
هر دو روشی که گفتید رو اعمال کردم ولی بازم برای تکست باکس همون خطارو میده!
به جای AppendTextBox من همون txtRecieveData.AppendText و به جای Invoke ، BeginInvokeنوشتم چون بدون این تغییرات اجرا نمیکرد

elyas_delshadnbe
شنبه 26 مهر 1393, 10:30 صبح
ميشه يه كم كدتونو كاملتر بذاريد ببينم چيه؟

elyas_delshadnbe
شنبه 26 مهر 1393, 10:31 صبح
اينا 2 تا روش نيستن. يه روشه كه كدشو كامل كردم فقط

elahe1393
شنبه 26 مهر 1393, 10:43 صبح
ممنون بله میدونم یه روش هست منم هر دو کد رو استفاده کردم ولی جواب نگرفتم
من رو دگمه شروع برنامه تابع زیر رو فراخوانی می کنم

private void Setting_Initialization()
{
_spManager = new SerialPortManager();
_spManager.NewSerialDataRecieved += new EventHandler<SerialDataEventArgs>(_spManager_NewSerialDataRecieved);
this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
}

بعد این تابع تو خودش تابع _spManager_NewSerialDataRecieved رو فراخوانی میکنه که کدش در زیر اومده


private void _spManager_NewSerialDataRecieved(object sender, SerialDataEventArgs e)
{
string str;
if (this.InvokeRequired)
{
str = Encoding.ASCII.GetString(e.Data);
AppendTextBox(str);
return;
}
}

بعدش کد AppendTextBox رو اینطوری نوشتم

private void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.BeginInvoke(new Action<string>(txtRecieveData.AppendText), new object[] { value });
return;
}
txtRecieveData.Text += value + "\r\n";
}

موقع اجرا هیچ رشته ای به تکست باکس اضافه نمیشه خطایی هم نمیده وقتی روی خط کدی که از txtRecieveData استفاده شده break بذارم تو بخش text این متن خطا رو نوشته
من از این تکست باکس تو یه تابعی که تو همون کد دکمه شروع فراخوانی کردم استفاده کردم تا رشته درونشو تفکیک کنم

elyas_delshadnbe
شنبه 26 مهر 1393, 10:55 صبح
به جاي txtRecieveData.AppendText كه AppendText رو ميذاريد اجرا نميكنه يا خطا ميده؟اگه خطا ميده خطاش چيه؟
روي AppendTextBox(str); در تابع _spManager_NewSerialDataRecieved يه breakpoint بذاريد ببينيد واقعا يه string و همون چيري رو كه ميخاين برميگردونه يا نه؟

elahe1393
شنبه 26 مهر 1393, 11:00 صبح
اول همون AppendText بود دیدم هیچ رشته ای به تکست باکس اضافه نمیشه خطایی هم نمیده فقط هم یک بار اجراش میکنه دیدم جواب نگرفتم بعد به txtRecieveData.AppendText تغییر دادم
بله str یه رشته تحویل میده

elyas_delshadnbe
شنبه 26 مهر 1393, 11:02 صبح
اگه مقدوره براتون برنامه رو كامل بذاريد تا ببينم چشه

elahe1393
شنبه 26 مهر 1393, 11:03 صبح
چیزی که از سرچ تو گوگل فهمیدم این خطا موقعیه که به یه کنترل که تو thread های دیگه استفاده شده نمیتونم بطور مستقیم تو threadجدید دسترسی پیدا کنم رخ میده هر تغییری که گفته بودن دادم ولی به جواب نرسیدم خطا موندگاره حالا شاید برداشتم اشتباست به هر حال میخوام مشکلم حل بشه

elahe1393
شنبه 26 مهر 1393, 11:05 صبح
برنامه خیلی زیاده کمی پیچیده است تو کل برنامه من تو این بخشش گیر کردم که میخوام با یه دستگاه از طریق پورت سریال ارتباط برقرار کنم حین ارتباط میخوام داده های ارسالی از طرف دستگاه رو بگیرم پردازش کنم همه چی درسته اون تیکه مشکل هست که میخوام دائما بطور موازی با پردازش داده از دستگاه دریافت کنم کل بخشی که گفتم تو این چندتا تابعی که تو پستهای قبلی نوشتم خلاصه میشه

elyas_delshadnbe
شنبه 26 مهر 1393, 11:06 صبح
ببينيد مشكلتون فك كنم از اينجا باشه. ما كنرل تمام تكست باكس ها و محتويات فرم رو فقط ميتونيم از طريق thread اصلي برنامه به دست بگيريم و وقتي شما ميخاين از يه thread كه خودتون ساختين اينا رو كنترل كنيد بايد اونو با پاس بدين به thread اصلي.حالا اگه مقدوره كد كامل پرو»تونو بدين تا ببينم چه مشكلي داره

elyas_delshadnbe
شنبه 26 مهر 1393, 11:14 صبح
اين تغييرات رو اعمال كنيد و نتيجه رو بگيد



private void _spManager_NewSerialDataRecieved(object sender, SerialDataEventArgs e)
{
string str = Encoding.ASCII.GetString(e.Data);
AppendTextBox(str);
return;
}



private void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendText), new object[] { value });
return;
}
txtRecieveData.Text += value + "\r\n";
}

elahe1393
شنبه 26 مهر 1393, 11:23 صبح
AppendText رو میگه وجود نداره به چی تغییر بدم چطوری تعریفش کنم؟

elyas_delshadnbe
شنبه 26 مهر 1393, 11:36 صبح
بكنيدش


this.Invoke(new Action<string>(AppendTextBox), new object[] { value });

elyas_delshadnbe
شنبه 26 مهر 1393, 11:39 صبح
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });

elahe1393
شنبه 26 مهر 1393, 11:43 صبح
اجرا کردم اول اینکه وقتی Invoke هست اصلا رو خط return نمیره و فقط یکبار تا این خط اجرا میشه خطایی هم نمیده به همین خاطر به BeginInvoke تغییر دادم اجرا شد
دوم اینکه دائما تو این شرط InvokeRequired میچرخه و هیچ رشته ای به تکست باکس اضافه نمیشه در صورتیکه value دارای مقدار است

gerdioz
شنبه 26 مهر 1393, 12:02 عصر
سلام تو قسمن برنامه تون این کد رو اضافه کنید
public Form1() {
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;


}

elyas_delshadnbe
شنبه 26 مهر 1393, 12:06 عصر
خب وقتي Invoke هست درسته ديگه. ما فقط يه بار لازم داريم كه كنترل برگرده به نخ اصلي. اونو بكنيد همون invoke.لازم نيست return رو اجرا كنه چون به اون خط كه مي رسه دوباره داره يه appendtextbox جديد new مي كنه. اين كارو بكنيد بعد بگيد حالا چه اتفاقي ميوفته

elahe1393
شنبه 26 مهر 1393, 12:16 عصر
الان من با تغییر هر دو حالت CheckForIllegalCrossThreadCalls = false; و Invoke بازم تکست باکسم خالیه وقتی میرم تو تابعی که از این تکست باکس استفاده میکنه رشته ای وجود نداره که پردازش کنه این خطا به حول و قوه الهی هنوز پابرجاست

elahe1393
شنبه 26 مهر 1393, 12:20 عصر
خب وقتي Invoke هست درسته ديگه. ما فقط يه بار لازم داريم كه كنترل برگرده به نخ اصلي. اونو بكنيد همون invoke.لازم نيست return رو اجرا كنه چون به اون خط كه مي رسه دوباره داره يه appendtextbox جديد new مي كنه. اين كارو بكنيد بعد بگيد حالا چه اتفاقي ميوفته

راستی یه سوال خوب اگه یه appendtextbox جدید میسازه از کجا میفهمه باید به کدوم تکست باکس مقدار رشته رو اضافه کنه؟!

elyas_delshadnbe
شنبه 26 مهر 1393, 12:20 عصر
شما منطق كار با thread هاتون مشكل داره. ميشه بگين دقيقا دارين چيكار مي كنين؟thread ها رو توضيح بدين و . . .

elyas_delshadnbe
شنبه 26 مهر 1393, 12:25 عصر
وقتي به اين خط مي رسه
this.Invoke(newAction<string>(AppendTextBox), newobject[] { value });
يه appendtextbox جديد ساخته ميشه كه چون با invoke همراه شده كنترلش دست thread اصلي برنامه هست و وقتي ساخته ميشه دوباره تابع appendtextbox فراخواني ميشه با اين تفاوت كه چون invokerequired==false هست ديگه appendtextbox جديدي new نميشه و خط
txtRecieveData.Text += value + "\r\n";
اجرا ميشه و محتويات شما داخل textbox نشون داده ميشن.

elahe1393
شنبه 26 مهر 1393, 12:32 عصر
برنامه با دستگاهی از طریق پورت سریال ارتباط داره وقتی دکمه شروع تو برنامه کلیک میشه من از طریق تابع Setting_Initialization تنظیمات اولیه رو برقرار میکنم که کد تابع مطابق زیر هست

private void Setting_Initialization()
{
_spManager.NewSerialDataRecieved += new EventHandler<SerialDataEventArgs>(_spManager_NewSerialDataRecieved);
this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
}
بعد چون میخوام حین ارتباط رشته های ارسالی از دستگاه رو هم دریافت کنم از تابع _spManager_NewSerialDataRecieved استفاده کردم که این تابع بطور موازی با شروع ارتباط اجرا میشه

private void _spManager_NewSerialDataRecieved(object sender, SerialDataEventArgs e)
{
string str = Encoding.ASCII.GetString(e.Data);
AppendTextBox(str);
{
طبق گفته شما AppendTextBox هم شد تابع زیر

private void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
txtRecieveData.Text += value + "\r\n";
}

توی فرم اصلی هم این تغییر رو دادم

public WorkWithDevice(string patientCode)
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
lblPatientCode.Text = patientCode;
}

تو رویداد کلیک دکمه شروع تابع InsertSpeedDataInReapet فراخوانی کردم که روی رشته درون تکست باکس پردازش میکنه که کدش مطابق زیر هست

public void InsertSpeedDataInReapet(string startPoint, string endPoint, string rightHardnessLevel, string reapetID, int reapetNumber, string sid)
{
string match;
Match regMatch;
bool find = false;

while (find == false)
{
if (reapetNumber == 1)
{
match = "PWM2=" + rightHardnessLevel;
}
else
{
match = "#";
}

regMatch = Regex.Match(txtRecieveData.Text, match);
string validRecieveData = txtRecieveData.Text.Substring(regMatch.Index + regMatch.Length);

string[] recieveDataSplit = validRecieveData.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);


if (recieveDataSplit.Length != 0)
{
for (int i = 0; i < recieveDataSplit.Length; i++)
{
if (recieveDataSplit[i].Length >= 20 && recieveDataSplit[i].Length <= 34)
{
string[] recieveDataPack = recieveDataSplit[i].Split(new char[] { '$', ',', '#' }, StringSplitOptions.RemoveEmptyEntries);

pointSpeed data = new pointSpeed();
data.LeftHardnessLevel = int.Parse(recieveDataPack[1]);
data.LeftSpeed = int.Parse(recieveDataPack[2]);
data.LeftPoint = ((int.Parse(recieveDataPack[3]) * 360) / 800).ToString();
data.RightHardnessLevel = int.Parse(recieveDataPack[4]);
data.RightSpeed = (-1) * int.Parse(recieveDataPack[5]);
data.RightPoint = ((-1) * (int.Parse(recieveDataPack[6]) * 360) / 800).ToString();
DrawChart(data, sid, startPoint, endPoint, reapetID, reapetNumber);
if (sid == "Left")
{
if (data.LeftPoint == endPoint)
find = true;
}
else if (sid == "Right")
{
if (data.RightPoint == endPoint)
find = true;
}
}
}
}
}
}

حالا طبق توضیحات من امیدوارم منطق thread هام خوب ادا شده باشه حالا مشکل کجاست؟

elahe1393
شنبه 26 مهر 1393, 12:38 عصر
وقتي به اين خط مي رسه
this.Invoke(newAction<string>(AppendTextBox), newobject[] { value });
يه appendtextbox جديد ساخته ميشه كه چون با invoke همراه شده كنترلش دست thread اصلي برنامه هست و وقتي ساخته ميشه دوباره تابع appendtextbox فراخواني ميشه با اين تفاوت كه چون invokerequired==false هست ديگه appendtextbox جديدي new نميشه و خط
txtRecieveData.Text += value + "\r\n";
اجرا ميشه و محتويات شما داخل textbox نشون داده ميشن.

پس الان مشکل برنامه ام کجاست که هی دائما appendtextbox جدید میسازه چطوری میتونم کنترل رو از چنگ thread اصلی دربیارم که بتونم به تکست باکسم تو این thread رشته اضافه کنم؟

elyas_delshadnbe
شنبه 26 مهر 1393, 12:40 عصر
شايد من خوب thread رو بلد نيستم ولي هيچ thread جديدي كه شما new كرده باشين نميبينم. :افسرده:

elahe1393
شنبه 26 مهر 1393, 12:49 عصر
شايد من خوب thread رو بلد نيستم ولي هيچ thread جديدي كه شما new كرده باشين نميبينم. :افسرده:

اختیار دارید من زیاد با موازی سازی آشنا نیستم چیزی که تو برنامه من درنظر گرفته شده اینه که چندتا کلاس تعریف شده و توابعی کد نویسی شده که کار با پورت سریال رو انجام میده با خط زیر تابع _spManager_NewSe rialDataRecieved دائما اجرا میشه و بصورت موازی میتونه داده های ارسالی دستگاه رو دریافت کنه
_spManager.NewSerialDataRecieved += new EventHandler<SerialDataEventArgs>(_spManager_NewSe rialDataRecieved);

من هیچ جایی thread نساختم thread اصلی که همون روال عادی فرم هست موازیشم دریافت داده از طریق تابع _spManager_NewSe rialDataRecieved الان داده ها دریافت میشه و مقدار str نشان دهنده اون مقدار هست حالا میخوام این مقدار به تکست باکس اضافه بشه الان مشکلی که وجود داره کنترل تکست باکس دائما دست فرم اصلی هست و تو تابع AppendTextBox نمیتونم به این کنترل دسترسی پیدا کنم چه کنم؟
بدبختی اینه که انقدر رو اون کلاسها کار شده که نمیتونم ازش دل بکنم یه روش دیگه پیش بگیرم نمیدونم شاید روشم به کل اشتباست با موازی سازی مشکل دارم راه حلم چیه؟

elyas_delshadnbe
شنبه 26 مهر 1393, 12:56 عصر
خب به نظر من اين كارتون اشتباه هست. ما وقتي ميخايم يه پردازش موازي رو انجام بديم كه دائما داره تكرار ميشه بايد يه thread مخصوص همون كار بسازيم تا thread اصلي بتونه به رويدادهاي فرممون پاسخ بده. شما اگه الان واسه همه كاراتون دارين از thread اصلي استفاده مي كنين اين كار رو امتحان كنيد تا متوجه اشتباهتون بشيد. يه button ديگه رو فرمتون بذاريد حالا وقتي برنامه اجرا شد سعي كنيد روش كليك كنيد. احتمالا نميتونيد چون main thread يه جاي ديگه مشغوله و نميتونه يه رويداد كليك شما پاسخ بده

elahe1393
شنبه 26 مهر 1393, 13:07 عصر
مرسی از راهنماییهاتون بنظر شما من دو تا کد مربوط به ارتباط که تو رویداد کلیک دکمه شروع نوشتم رو جدا کنم مثل زیر
private void StartConnect()
{
Setting_Initialization();
_spManager.StartListening();
}

بعد تو رویداد کلیک دکمه شروع بیام این کد بنویسم new Thread(StartConnect).start(); مشکل حل میشه؟

elyas_delshadnbe
شنبه 26 مهر 1393, 13:13 عصر
آره همه كاراتونو تا قبل گوش دادن تو Thread اصلي انجام بدين بعد واسه Listening يه Thread جديد بسازين و همه كارهاي مربوط به گوش دادن رو داخل اون انجام بدين. بعد به راحتي با استفاده از تابع AppendTextBox ميتونيد محتويات رو داخل textbox نشون بدين. و اينم بگم كه اون كارتون كه داخل main thread مياين و invoke مي كنيد بي معنيه و دليلي نداره درست كار كنه. بازم اگه وقت كنم يه برنامه كوچيك واستون مينويسم تا دقيقا نحوه استفادشو متوجه بشين

elahe1393
شنبه 26 مهر 1393, 13:17 عصر
مرسی باید تستش بکنم
موفق باشید

elyas_delshadnbe
شنبه 26 مهر 1393, 22:00 عصر
یه برنامه کوچیک براتون نوشتم امیدوارم به درک مفهوم ماجرا کمکت کنه. اون error هم دقیقا مال استفاده از thread اصلی است برای پردازش موازی

elahe1393
یک شنبه 27 مهر 1393, 08:12 صبح
مرسی از مثال و راهنماییتون

elahe1393
یک شنبه 27 مهر 1393, 10:44 صبح
در حال حاضر اون مشکل حل شد ولی مشکل جدیدی که هست اینه که وقتی من thread میسازم همزمان با thread اصلی اجرا میشه ولی وقتی من تابعی که میخواد تفکیک سازی رشته درون تکست باکس رو انجام بده فراخوانی میکنم دیگه اون خواندن اطلاعات بصورت موازی انجام نمیشه من میخوام وقتی تو تابع رفتم تا وقتی که توی رشته دریافتی که به تکست باکس اضافه میشه مقدار مشخصی رو دریافت نکردم همینجور به تفکیک سازی ادامه بده پس نیاز دارم خوندن اطلاعات بصورت موازی با تفکیک سازی رشته ادامه پیدا کنه چیکار باید بکنم مشکل کجاست؟

elyas_delshadnbe
یک شنبه 27 مهر 1393, 10:50 صبح
يه توضيح بدين چيو داخل textbox ميريزين و ميخواين چي رو پردازش كنيد؟

elyas_delshadnbe
یک شنبه 27 مهر 1393, 11:05 صبح
ببينيد ما وقتي اساسا از پردازش موازي صحبت ميكنيم به اين معنا نيست كه واقعا اين دو كار داره همزمان انجم ميشه. بلكه به نظر ما اينجوري ميرسه. در واقع CPU داره مرتب بين اون دو پردازش زمانو تقسيم ميكنه. مثلا اگه 1 ثانيه رو در نظر بگيريد. نيم ثانيه در اختيار پردازش اوله و نيم ثانيه بعدي در اختيار پردازش دوم. حالا چون اين كار خيلي سريع انجام ميشه به نظر ما ميرسه كه داره دو كار رو همزمان انجام ميده. و علت اين مشكل شما هم دقيقا همينه. وقت كنم يه برنامه واستون ميذارم. مطمئنم كمكتون ميكنه. هم مفهومو ميفهميد و هم دقيقا به درد همين برنامه تون ميخوره.

elahe1393
یک شنبه 27 مهر 1393, 11:09 صبح
برنامه با دستگاهی از طریق پورت سریال ارتباط داره وقتی دکمه شروع تو برنامه کلیک میشه من از طریق تابع Setting_Initialization تنظیمات اولیه رو برقرار میکنم که کد تابع مطابق زیر هست

private void Setting_Initialization()
{
_spManager.NewSerialDataRecieved += new EventHandler<SerialDataEventArgs>(_spManager_NewSerialDataRecieved);
this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
}
بعد چون میخوام حین ارتباط رشته های ارسالی از دستگاه رو هم دریافت کنم از تابع _spManager_NewSerialDataRecieved استفاده کردم که این تابع بطور موازی با شروع ارتباط اجرا میشه

private void _spManager_NewSerialDataRecieved(object sender, SerialDataEventArgs e)
{
string str = Encoding.ASCII.GetString(e.Data);
AppendTextBox(str);
{
طبق گفته شما AppendTextBox هم شد تابع زیر

private void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
txtRecieveData.Text += value + "\r\n";
}

توی فرم اصلی هم این تغییر رو دادم

public WorkWithDevice(string patientCode)
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
lblPatientCode.Text = patientCode;
}

تو رویداد کلیک دکمه شروع تابع InsertSpeedDataInReapet فراخوانی کردم که روی رشته درون تکست باکس پردازش میکنه که کدش مطابق زیر هست

public void InsertSpeedDataInReapet(string startPoint, string endPoint, string rightHardnessLevel, string reapetID, int reapetNumber, string sid)
{
string match;
Match regMatch;
bool find = false;

while (find == false)
{
if (reapetNumber == 1)
{
match = "PWM2=" + rightHardnessLevel;
}
else
{
match = "#";
}

regMatch = Regex.Match(txtRecieveData.Text, match);
string validRecieveData = txtRecieveData.Text.Substring(regMatch.Index + regMatch.Length);

string[] recieveDataSplit = validRecieveData.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);


if (recieveDataSplit.Length != 0)
{
for (int i = 0; i < recieveDataSplit.Length; i++)
{
if (recieveDataSplit[i].Length >= 20 && recieveDataSplit[i].Length <= 34)
{
string[] recieveDataPack = recieveDataSplit[i].Split(new char[] { '$', ',', '#' }, StringSplitOptions.RemoveEmptyEntries);

pointSpeed data = new pointSpeed();
data.LeftHardnessLevel = int.Parse(recieveDataPack[1]);
data.LeftSpeed = int.Parse(recieveDataPack[2]);
data.LeftPoint = ((int.Parse(recieveDataPack[3]) * 360) / 800).ToString();
data.RightHardnessLevel = int.Parse(recieveDataPack[4]);
data.RightSpeed = (-1) * int.Parse(recieveDataPack[5]);
data.RightPoint = ((-1) * (int.Parse(recieveDataPack[6]) * 360) / 800).ToString();
DrawChart(data, sid, startPoint, endPoint, reapetID, reapetNumber);
if (sid == "Left")
{
if (data.LeftPoint == endPoint)
find = true;
}
else if (sid == "Right")
{
if (data.RightPoint == endPoint)
find = true;
}
}
}
}
}
}

حالا طبق توضیحات من امیدوارم منطق thread هام خوب ادا شده باشه حالا مشکل کجاست؟

طبق این پست و توضیحاتی که داده شده من اومدم یه thread ساختم و Setting_Initialization() رو داخلش قرار دادم تا بصورت موازی داده دریافت کنه اینکار انجام میشه تا قبل از اینکه تو رویداد کلیک دکمه شروع به فراخوانی تابع InsertSpeedDataInReapet میرسم وقتی وارد این تابع میشه دیگه اون thread اجرا نمیشه من میخوام تا زمانیکهیکی از این شرطهام
if (sid == "Left") {
if (data.LeftPoint == endPoint)
find = true;
}
else if (sid == "Right")
{
if (data.RightPoint == endPoint)
find = true;
}


برقرار نشده این تفکیک سازی رشته درون تکست باکسم ادامه پیدا کنه
من تو این دو خط از اون تکست باکس استفاده کردم
regMatch = Regex.Match(txtRecieveData.Text, match); string validRecieveData = txtRecieveData.Text.Substring(regMatch.Index + regMatch.Length);


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

elyas_delshadnbe
یک شنبه 27 مهر 1393, 11:11 صبح
واسه اين كار شما بايد به thread ي كه مسئول نوشتن در textbox هست فرمان توقف بدبد تا زماني كه كار thread پردازشگر textbox خاتمه پيدا كنه. ميتونيد از دستور join ويا دستورات wait و set استفاده كنيد

elyas_delshadnbe
یک شنبه 27 مهر 1393, 11:16 صبح
یه سوال دیگه دارم اگه تابعی که میخوام موازی اجرا بشه نیاز به پارامتر ورودی داشته باشه چطوری باید thread رو تعریف کنم؟


معمولا thread رو داخل يه كلاس تعريف ميكنن. ميتونيد داخل همون كلاس يه متغير سراسري به صورت Private تعريف كنيد و بعد توي همه ي thread هاي همون كلاستون ازش بهره برداري كنيد.

elahe1393
یک شنبه 27 مهر 1393, 11:17 صبح
خوب من نمیخوام اون thread توقف کنه چون داده هایی که حین اجرای این تابع از طرف دستگاه ارسال میشه برام مهمه و میخوام دریافت کنم تا تکرار بعدی حلقه while اون داده ها به تکست باکس اضافه بشه تا بتونم اونارو هم بررسی کنم

elyas_delshadnbe
یک شنبه 27 مهر 1393, 11:24 صبح
خوب من نمیخوام اون thread توقف کنه چون داده هایی که حین اجرای این تابع از طرف دستگاه ارسال میشه برام مهمه و میخوام دریافت کنم تا تکرار بعدی حلقه while اون داده ها به تکست باکس اضافه بشه تا بتونم اونارو هم بررسی کنم

اگه از يه سيستم دارين داده ميگيرين هيچ نگراني بابت اين موضوع وجود نداره. اين توقف چشمگير نيست و به احتمال قوي هيچ داده اي رو از دست نميدين.

elahe1393
یک شنبه 27 مهر 1393, 11:31 صبح
اگه از يه سيستم دارين داده ميگيرين هيچ نگراني بابت اين موضوع وجود نداره. اين توقف چشمگير نيست و به احتمال قوي هيچ داده اي رو از دست نميدين.

بله یه سیستم هست ولی الان که break در هر thread گذاشتم وقتی میره تو تابع تفکیک سازی دیگه تو thread دریافت داده نمیره بخاطر همین دیگه چیزی به تکست باکس اضافه نمیشه به همین دلیل من مقدار موردنظرمو نمیتونم تو رشته تکست باکس پیدا کنم چون مقدار تکست باکس تغییر نکرده و دائما تو حلقه while میچرخه و برنامه قفل میشه

elyas_delshadnbe
یک شنبه 27 مهر 1393, 11:39 صبح
يه نمونه برنامه كوچيك. از همين روش استفاده كنيد مطمئن باشد جواب ميگيرين

hamid_hr
یک شنبه 27 مهر 1393, 11:40 صبح
شما برا تحلیل اون مقادیر تکست باکستون یه تا بع بنویسین با ورودی یه رشته
تو رویداد textchange اون تکس باکس اون تابعو صدا بزنین و تکست رو بهش پاس بدین
اینطوری هم تحلیل انجام میشه هم اون ترد اولتون کارش مختل نمیشه

ویرایش : تو رویداد textchange اون تکس باکس اون تابعو با ترد صدا بزنین و تکست رو بهش پاس بدین

elahe1393
یک شنبه 27 مهر 1393, 12:09 عصر
يه نمونه برنامه كوچيك. از همين روش استفاده كنيد مطمئن باشد جواب ميگيرين

مرسی که برای کمک وقت میزارید من با موازی سازی آنچنان آشنا نیستم الان join، wait و Set چه کاری انجام میدن چه مواقعی استفاده میشه الان منطق برنامه رو متوجه نشدم :ناراحت:

elahe1393
یک شنبه 27 مهر 1393, 12:12 عصر
شما برا تحلیل اون مقادیر تکست باکستون یه تا بع بنویسین با ورودی یه رشته
تو رویداد textchange اون تکس باکس اون تابعو صدا بزنین و تکست رو بهش پاس بدین
اینطوری هم تحلیل انجام میشه هم اون ترد اولتون کارش مختل نمیشه

ویرایش : تو رویداد textchange اون تکس باکس اون تابعو با ترد صدا بزنین و تکست رو بهش پاس بدین

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

elyas_delshadnbe
یک شنبه 27 مهر 1393, 12:33 عصر
الان منطق برنامه رو متوجه نشدم :ناراحت:

شما AutoResetEventForBarnamenevis رو نگاه كردين؟

elahe1393
یک شنبه 27 مهر 1393, 12:43 عصر
شما AutoResetEventForBarnamenevis رو نگاه كردين؟

بله نگاه کردم ولی منطق استفاده از wait و set رو نفهمیدم الان بخوام تو برنامه ام استفاده کنم نمیدونم چیکار باید بکنم؟

jir_jir_jir
یک شنبه 27 مهر 1393, 19:22 عصر
تا دوستان برنامه شمارو نبینن این بحث ادامه خواهد داشت برنامه تون رو بزارید تا دوستانی که توانایی دارن روش کار کنن تا مشگلتون حل بشه

elyas_delshadnbe
دوشنبه 28 مهر 1393, 07:53 صبح
وقتي شما با دو تا thread كار مي كنيد مي تونيد ي كاري بكنيد كه يه Thread منتظر اون يكي بمونه تا وقتي يه كار خاص اون ور انجام شد اين يكي بقيه كاراشو انجام بده. استفاده از دستورات wait و set مربوط ميشه به AutoResetEvent كه به همين منظور استفاده ميشه. شما داخل تابعي كه در textbox مينويسه بايد يه wait بديد و بعد اون در نخ مربوط به پردازش textbox بعد اين كه كارش تمام شد eventhandeler رو دوباره Set مي كنيد. به اين ترتيب اطمينان پيدا مي كنيد كه هيچ وقت هيچ چيزي از Textbox رو از دست نميديد و همه موارد كاملا پردازش ميشه.

elyas_delshadnbe
دوشنبه 28 مهر 1393, 07:58 صبح
نحوه تعريف AutoResetEvent:
EventWaitHandle wh = new AutoResetEvent(false);
و يا

EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset);

براي استفاده از اين بايد كتابخونه using System.Threading; رو به پرو»تون اضافه كنين كه حتما اين كارو كردين تا حالا.

elyas_delshadnbe
دوشنبه 28 مهر 1393, 08:01 صبح
راستي دو متد wait و set هم برميگرده به همين همونطور كه گفتم
wh.WaitOne()
فرمان توقف رو صادر مي كنه و wh.Set() فرمان از سرگيري مجدد رو صادر مي كنه.

چندتا تشكرم بكنين آدم دلگرم ميشه :تشویق:

elahe1393
دوشنبه 28 مهر 1393, 08:12 صبح
خیلی ممنون از راهنمایی و توضیحتون باید تستش بکنم ببینم جواب میده دیشب خیلی کار کردم روش ولی به نتیجه دلخواه نرسیدم امیدوارم با این توضیحاتتون به نتیجه برسم :تشویق::تشویق::تشویق: