PDA

View Full Version : اشکال این برنامه چیه ؟



Ghasem Dehghani
پنج شنبه 17 خرداد 1386, 12:10 عصر
با سلام .
من یک برنامه نوشتم تا عکس های موجود در یک دایرکتوری را به صورت کوچک در داخل دکمه ها نمایش بدهد (دکمه ها در داخل یک Panel قرار میگیرند) و کاربر با کلیک بر روی هر دکمه میتواند عکس زمینه فرم را مطابق عکس هر دکمه تغییر دهد .
اما مشکل اینجا بود که اگر تعداد عکس های بالا باشد تا چند لحظه دسترسی به برنامه قطع میشد به همین دلیل اون رو داخل یک Theard قرار دادم ولی تا وقتی داخل ترد قرار ندارد درست کار میکند ولی هنگامی که داخل ترد قرار میگیرد نمی تواند متد New را که برای ایجاد دکمه جدید است را فراخوانی کند .
لطفا مرا راهنمایی کنیم .
با تشکر و سپاس فراوان .
کد برنامه :


namespace WindowsApplication3
{
public partial class Form1 : Form
{
Thread th;
public Form1()
{
InitializeComponent();
}

int i = 0;
string path = "";
Button pic;

void showpic()
{
textBox1.Text = path;
foreach (string s in System.IO.Directory.GetFiles(path))
{
try
{
pic = new Button();
System.Threading.Thread.Sleep(500);
pic.Name = "Pic" + i.ToString();
pic.BackgroundImage = Image.FromFile(s);
pic.BackgroundImageLayout = ImageLayout.Zoom;
pic.FlatStyle = FlatStyle.Flat;
pic.Text = "";
pic.Height = 50;
pic.Width = 50;
pic.Top = (int)(i / 4) * pic.Size.Height;
pic.Left = (int)(i % 4) * pic.Size.Width;
pic.Click += new EventHandler(button2_Click);
panel1.Controls.Add(pic);
panel1.Refresh();
++i;
Text = s;
}
catch { }
}
}

private void button2_Click(object sender, EventArgs e)
{
this.BackgroundImage = ((Button)sender).BackgroundImage;
}

private void button1_Click(object sender, EventArgs e)
{
Application.DoEvents();
try
{
th.Abort();
}
catch { }
if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
{
path = folderBrowserDialog1.SelectedPath;
th = new Thread(new ThreadStart(showpic));
th.Start();
}
}

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
th.Abort();
}
catch { }
}

private void button2_Click_1(object sender, EventArgs e)
{
try
{
th.Abort();
}
catch { }
}
}
}

kiani.mehdi
پنج شنبه 17 خرداد 1386, 16:01 عصر
کد زیر را اول رویداد لود فرم یا در construcotr فرم بعد از initializeComponent بذار شاید مشکلت حل بشه





Control.CheckForIllegalCrossThreadCalls = false;


موفق باشید
مهدی کیانی

Ghasem Dehghani
پنج شنبه 17 خرداد 1386, 17:27 عصر
با سلام خدمت آقای کیانی .
کد شما را تست کردم ولی متاسفانه جواب نداد ، آیا راه دیگه ای به نظرتون میرسه .

kiani.mehdi
پنج شنبه 17 خرداد 1386, 22:31 عصر
دقیقا بگین چه خطایی بهتون میده

Alireza_Salehi
پنج شنبه 17 خرداد 1386, 23:22 عصر
ارتباط بین چند thread (در اینجا Thread اصلی و Thread ی که شما ایجاد کردید - ممکنه باعث اختلال در برامه بشه چون ممکنه دستکاری همزمان در آبجکت ها به طور صحیح انجام نشه، راه صحیح ارتباط در مقاله زیر توضیح داده شده)
این مقاله رو بخونید راه حل مشکل شماست:(البته کافی بود به راهنمایی های ویژوال استودیو هنگام Exception توجه می کردید!)
How to: Make Thread-Safe Calls to Windows Forms Controls (http://msdn2.microsoft.com/en-us/library/ms171728.aspx)

در ضمن اگر به جای نسبت دادن عکسهایی که احتمالا سایز بزرگی هم دارند به دکمه ها از متد GetThumbnailImage کلاس Image استفاده کنید و عکس های کوچک تری به دکمه ها نسبت بدید نهایتا برنامه سرعت بیشتری خواهد داشت.