PDA

View Full Version : سوال در مورد Thread و Task



arastoahmadi
چهارشنبه 06 اسفند 1399, 09:37 صبح
باسلام

دوستان من یه متد به شکل زیر دارم که یه مقدار رو برمیگردونه و داخل حلقه while گذاشتم که مقدار به متغییر اضافه بشه و برگردونه حالا من میخام از یه تر استفاده کنم و مقداربرگشتی حاصل از این متد رو داخل یه label نمایش بدم ، دوستان چطوری باید این کارو انجام بدم چون من یه کدی به شکل زیر نوشتم اما متاسفانه کار نمیکنه


private void button2_Click(object sender, EventArgs e)
{
Thread t;
t = new Thread(() =>
{
this.BeginInvoke((MethodInvoker)delegate
{
label1.Text = ReturnValue(1).ToString();
});

});
t.Start();

}

public int ReturnValue(int n)
{


while (true)
{
n += 1;
Thread.Sleep(1000);
return n;
}

}

the king
چهارشنبه 06 اسفند 1399, 13:50 عصر
باسلام

دوستان من یه متد به شکل زیر دارم که یه مقدار رو برمیگردونه و داخل حلقه while گذاشتم که مقدار به متغییر اضافه بشه و برگردونه حالا من میخام از یه تر استفاده کنم و مقداربرگشتی حاصل از این متد رو داخل یه label نمایش بدم ، دوستان چطوری باید این کارو انجام بدم چون من یه کدی به شکل زیر نوشتم اما متاسفانه کار نمیکنه


private void button2_Click(object sender, EventArgs e)
{
Thread t;
t = new Thread(() =>
{
this.BeginInvoke((MethodInvoker)delegate
{
label1.Text = ReturnValue(1).ToString();
});

});
t.Start();

}

public int ReturnValue(int n)
{


while (true)
{
n += 1;
Thread.Sleep(1000);
return n;
}

}


این کدی که شما برای ReturnValue نوشته اید با این فرقی نداره :

public int ReturnValue(int n)
{
n += 1;
Thread.Sleep(1000);
return n;
}

و با این کدی که نوشته اید با Thread جانبی هیچ کار مستقلی انجام نمی دهید، از همون اول همه روال رو با BeginInvoke حواله کرده اید به Thread اصلی فرم.
ReturnValue رو Thread اصلی فرم فراخوانی می کنه، label1.Text رو هم Thread اصلی فرم مقدار دهی می کنه، دیگه کاری نمونده که new Thread خودش بخواد انجام بده.
Thread جانبی وقتی میتونه موثر باشه که کاری رو خودش انجام بده، مثلا ReturnValue رو خودش اجرا کنه.
اگه بخواهید همه روال رو با BeginInvoke در Thread اصلی انجام بدهید دیگه کاری برای Thread جانبی نمی مونه.

public int ReturnValue(int n)
{
n += 1;
Thread.Sleep(1000);
return n;
}

private void button2_Click( object sender, EventArgs e)
{
Thread t;
t = new Thread(() =>
{
var n = 1;
while (true)
{
var s = n.ToString();
this.BeginInvoke( (MethodInvoker)delegate { label1.Text = s; });
n = ReturnValue(n);
}
});
t.Start();
}



private void button2_Click(object sender, EventArgs e)
{
Thread t;
t = new Thread(() =>
{
var n = 1;
while (true)
{
Invoke(new Action<int>(SetLabelText), n);
n++;
Thread.Sleep(1000);
}
});
t.Start();
}

private void SetLabelText(int n)
{
label1.Text = n.ToString();
}

arastoahmadi
چهارشنبه 06 اسفند 1399, 16:14 عصر
ممنون از پاسختون دوست عزیز ، ;کارم راه افتاد حالا طیق فرمایشات شما من یه متد ایجاد کردم که صفحه دسکتاپ رو به صورت استریم نمایش میده ، سوال من اینه که متد نمایش صفحه دسکتاپ شامل پارامتر quality می باشد که کیفیت تصویر رو مشخص میکنه حالا من میخام تصویر رو با چن کیفیت مختلف نمایش بدم ولی نمیخام ترد دیگه ای ایجاد کنم و میخام ترد به صورت پویا خودش ایجاد بشه و مطابق درخواست من تصویر رو با کیفیت درخواستی ارسال کنه و همچنین درصورتی که توقف رکورد رو زدم ترد استارت شده abort یشه . منطورم اینه که من یه متد با عنوان ScreenCapture(int quality) دارم که کارش عکس از صفحه دسکتاپ توسط while هستش، حالا میخام وقتی کاربر ضبط تصویر با کیفیت 25 رو زد یه ترد تحت عنوان همین موضوع ایجاد بشه و درواقع مقدار بازگشتی یعنی return image رو به تابعی که سمت سرور نوشتم Invoke کنه ، دیگه از سمت سرور من خودم تعیین کردم که مقدار رو برای کدام کلاینت بفرسته. من هدفم اینه که ما یه سیستمی داریم و درواثع این متد رو تو برنامه نوشتیم و میخایم هرکاربری که این تابع رو از سیستم با quality مورد نظر فراخوانی کرد تصویر براش ارسال بشه و ممکنه چند کاربر درخواست تصویر بکننن و منم به ذهنم رسید شاید بهتر باشه که از ترد دینامیکی استفاده کنم یعنی ترد به صورت اتوماتیک براساس هر درخواست ایجاد بشه ، ممنون میشم منو تو این زمینه راهنمایی بفرمایید و اگه راه حل بهتری برای جایگزینی ایده من هست ممنون میشم مطرح بفرمایید



private static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
private void button2_Click(object sender, EventArgs e)
{
Thread t;
t = new Thread(() =>
{

while (true)
{
byte[] b = ScreenCapture(20);

this.BeginInvoke((MethodInvoker)delegate { pictureBox1.Image = Image.FromStream(new MemoryStream(b)); });

}
});
t.Start();

}
private byte[] ScreenCapture( int quality)
{
byte[] b = null;
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
System.Drawing.Imaging.Encoder QualityEncoder = System.Drawing.Imaging.Encoder.Quality;
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(QualityEncoder, quality);
MemoryStream memoryStream = new MemoryStream();
myEncoderParameters.Param[0] = myEncoderParameter;
bitmap.Save(memoryStream, jpgEncoder, myEncoderParameters);
String mem1 = Convert.ToBase64String(memoryStream.ToArray());
if (string.IsNullOrEmpty(mem2))
{
mem2 = Convert.ToBase64String(memoryStream.ToArray());
b = memoryStream.ToArray();
}
else
{
if (mem1.Equals(mem2))
{

//
}
else

{
var image = Image.FromStream(memoryStream);
b = memoryStream.ToArray();
mem2 = Convert.ToBase64String(memoryStream.ToArray());
}
}
Thread.Sleep(500);

return b;
}