PDA

View Full Version : سوال: خطا در ایجاد ترد وابسته به تابع بازگشتی رشته ای



MehdiElexal
پنج شنبه 26 تیر 1393, 15:03 عصر
با سلام مجدد
یک ترد ایجاد شده
public static string SendMessagePDU(string PhoneNumber,string MessageText,int WaitTime)
{
PhoneNumberPDU=PhoneNumber;
MessageTextPDU=MessageText;
WaitTimePDU=WaitTime;
ThreadStart entryPoint = new ThreadStart(SendPDU);
Thread depthChangeThread = new Thread(entryPoint);
depthChangeThread.Start();

}

تابع فراخوانی شده :
public static string SendPDU()
{
SMS sms = new SMS();
int lenghtMessage = 0;
try
{

GSMPORT.Encoding = Encoding.GetEncoding("utf-8");
sms.Direction = SMSDirection.Submited;
sms.PhoneNumber = "+98" + PhoneNumberPDU;//+989192071554
sms.ValidityPeriod = new TimeSpan(4, 0, 0, 0);
sms.Message = MessageTextPDU;
lenghtMessage = ((MessageTextPDU.Length) * 2) + 14;


GSMPORT.Write("AT+CMGS=" + lenghtMessage + "\r");
Thread.Sleep(WaitTimePDU);
GSMPORT.Write(sms.Compose(SMS.SMSEncoding.UCS2) + "\r");
Thread.Sleep(WaitTimePDU);
GSMPORT.Write(Char.ConvertFromUtf32(26));//Ctrl+Z

string PDUConvert;
PDUConvert = sms.Compose(SMS.SMSEncoding.UCS2);
return PDUConvert;

}

catch (Exception e)
{
throw new Exception("Error Send Message PDU");
}

}



خطا از خط
ThreadStart entryPoint = new ThreadStart(SendPDU);

متن خطا
Error 3 'string SIM900Module.SIM900ModuleClass.SendPDU()' has the wrong return type 271 38 SIM900Module



تابع من مقدار بازگشتی رشته ای داره
چطور حلش کنم ؟
با تشکر

abbas.oveissi
پنج شنبه 26 تیر 1393, 23:29 عصر
دلیل خطا اینه که ThreadStart یک دلیگیت هست که تابع های بدون مقدار بازگشتی با Void رو قبول میکنه.میتونید یدونه متغیر Global تعریف کنید و از داخل متد SendPDU اونو مقدار دهی کنید.اینم نمونه کد :
class Program
{
public static string value = "";
public static void runTask()
{
//bade hameye kar haaa
value = "test";
}


static void Main(string[] args)
{
Thread t = new Thread(new ThreadStart(runTask));
t.Start();
Console.WriteLine(value);
}
}

MehdiElexal
جمعه 27 تیر 1393, 15:56 عصر
دلیل خطا اینه که ThreadStart یک دلیگیت هست که تابع های بدون مقدار بازگشتی با Void رو قبول میکنه.میتونید یدونه متغیر Global تعریف کنید و از داخل متد SendPDU اونو مقدار دهی کنید.اینم نمونه کد :
class Program
{
public static string value = "";
public static void runTask()
{
//bade hameye kar haaa
value = "test";
}


static void Main(string[] args)
{
Thread t = new Thread(new ThreadStart(runTask));
t.Start();
Console.WriteLine(value);
}
}

درسته اما مثالی که شما زدی هیچ آرگومان ورودی نداره
ولی تابع من آرگومان باید داشته باشه
شما فرض کن تابعی داری که یه عدد میگیره تا کار انجام بده ینی runTask شما ورودی داشته باشه علاوه بر اینکه مقدار test رو تو value میریزه
اونوقت چی ؟
باتشکر

abbas.oveissi
جمعه 27 تیر 1393, 17:09 عصر
درسته اما مثالی که شما زدی هیچ آرگومان ورودی نداره
ولی تابع من آرگومان باید داشته باشه
شما فرض کن تابعی داری که یه عدد میگیره تا کار انجام بده ینی runTask شما ورودی داشته باشه علاوه بر اینکه مقدار test رو تو value میریزه
اونوقت چی ؟
باتشکر
به جای دلیگیت ThreadStart باید از اون یکی دلیگیت به اسم ParameterizedThreadStart استفاده کنید.جفتشون توابعی قبول میکنند که مقدار بازگشتی Void دارند اما در دلیگیت ParameterizedThreadStart تابع یک پارامتر ورودی از نوع Object هم میتونه قبول بکنه که ما ازش استفاده میکنیم:
public static string value = "";
class inputs
{
public int a;
public int b;
}

public static void runTask(object o)
{
inputs obj = (inputs)o;
Console.WriteLine(obj.a+obj.b);
}


static void Main(string[] args)
{
Thread t = new Thread(new ParameterizedThreadStart(runTask));
inputs inputObj = new inputs();
inputObj.a=10;
inputObj.b=20;
t.Start(inputObj);
Console.ReadKey();
}

MehdiElexal
شنبه 28 تیر 1393, 12:31 عصر
فقط نوع آبجکت قبول میکنه یا رشته و عدد هم قبول میکنه ؟ چون الان دسترسی ندارم میپرسم، با تشکر

aliagamon
شنبه 28 تیر 1393, 14:24 عصر
تو روش بالا باید ابجکت بفرستین
اما من خودم ترجیح میدم با lambda این کارو بکنم ... .

public static void runTask(int a,int b)
{
MessageBox.Show((a + b).ToString());
}

.
.
.
.
int a=3;
int b = 21;
Thread t = new Thread(()=> runTask(a,b));
t.Start();


اگرم میخواین return کنه از این استفاده کنین :

int a=3;
int b = 21;
int c = 0;
Thread t = new Thread(() => { c = runTask(a, b); });
t.Start();
Thread.Sleep(3);
MessageBox.Show(c.ToString());

دقت کنید اون وقفه ای که انداختم واسه اینه که عملیات جمع انجام بشه بعد نمایش بده ... شما بسته به عملیات اجرایی باید وقفه بزاری ... چون اگه قبل از اینکه تابع return کنه نمایش بده درواقع همون 0 رو بهتون میده .. (امیدوارم بفهمین چی میگم ... احساس میکنم گنگ گفتم:لبخند:)
البته با delegate هم میشه اما اگه از دات نت قدیمی استفاده نمیکنید این روش بهتره (البته فرقی نمیکنه ... :لبخند:)