PDA

View Full Version : سوال: تداخل در واکشی اطلاعات از database در رویداد TextChanged با استفاده از BackGroundWorker



daniyaltjm
شنبه 24 مهر 1395, 18:18 عصر
سلام، اشکال این کدها چیه چرا Theredها با هم تداخل میکنن؟! من می خوام در واقع هر وقت کاراکتری توی تکست باکس زده شد و در همین هنگامی که داده ها دارن واکشی میشن فقط یک circularProgress بچرخه و زمانی که کار BackGroundWorker تمام شد توی رویداد RunWorkerCompleted اون circularProgress دیگه نمایش داده نشه ولی ظاهرا گیر میده که تداخل میکنه با ترد قبلی !! کد های چک کردن هم گذاشتم ولی نمی دونم مشکل از کجاست؟:متفکر:
البته این کار رو با تایمر شبیه سازی کردم ولی می خوام دقیق انجام بشه ممنون.

private void backgroundWorkerSe_DoWork(object sender, DoWorkEventArgs e)
{
if (backgroundWorkerSe.CancellationPending)
{
e.Cancel = true;
Return;
}
else
{
SearchWords("select En_Text,Per_Text,Per_Means,Type from Words where En_Text like @En_Text order by En_Text asc ");

circularProgress1.Invoke(new Action(() =>
{
circularProgress1.IsRunning = true;
}));

}
}

private void radTextBoxSearch_TextChanged(object sender, EventArgs e)
{
if (!backgroundWorkerSe.IsBusy)
{
backgroundWorkerSe.RunWorkerAsync();
}
else
{
backgroundWorkerSe.CancelAsync();
}

}
private void backgroundWorkerSe_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
circularProgress1.Invoke(new Action(() =>
{
circularProgress1.IsRunning = false;
}));
}

public void SearchWords(string strcm)
{
try
{
OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Daniyal\Documents\Visual Studio 2013\Projects\Dani_ProDic\Dani_ProDic\Dic.mdb");
OleDbDataAdapter da = new OleDbDataAdapter(strcm, con);
da.SelectCommand.Parameters.AddWithValue("@En_Text", radTextBoxSearch.Text + "%");
DataTable dt = new DataTable();
da.Fill(dt);
radGridViewWords.DataSource = dt;
radGridViewWords.Columns[0].HeaderText = "کلمه";
radGridViewWords.Columns[1].HeaderText = "معنی";
radGridViewWords.Columns[2].IsVisible = false;
radGridViewWords.Columns[3].IsVisible = false;
textBoxTotalMeans.Text = radGridViewWords.CurrentRow.Cells[2].Value.ToString();

}
catch (Exception e)
{
MessageBox.Show(e.Message);
}

}

Mahmoud.Afrad
شنبه 24 مهر 1395, 21:24 عصر
رویداد DoWork در ترد دیگر اجرا میشه و نمی توان به کنترلها دسترسی مستقیم داشت.
دو راه دارید یا در متد SearchWorks از طریق Invoke مقدار کنترلها رو تغییر بدید یا اینکه دستکاری کنترلها رو به رویداد RunWorkerCompleted منتقل کنید.

daniyaltjm
شنبه 24 مهر 1395, 21:40 عصر
رویداد DoWork در ترد دیگر اجرا میشه و نمی توان به کنترلها دسترسی مستقیم داشت.
دو راه دارید یا در متد SearchWorks از طریق Invoke مقدار کنترلها رو تغییر بدید یا اینکه دستکاری کنترلها رو به رویداد RunWorkerCompleted منتقل کنید.

ممنون، خوب من بالا از Invoke استفاده کردم ولی با متد Action چرا جواب نمیده؟ میشه یکم توضیح با کد بیدن؟ بعد اگر توی رویداد RunWorkerCompleted کنترولمو نشون بدم یکم ناجور نیست؟ آخه رکورد ها واکشی شدن و بعد اون circularProgress1 بچرخه!

daniyaltjm
شنبه 24 مهر 1395, 22:35 عصر
همه کدهای مربوط به لود رکورد از دیتا بیس و غیر فعال کردن کنترول circularProgress رو بردم توی رویداد RunWorkerCompleted و توی رویداد DoWork هیچی ننوشتم و فقط توی رویداد تکست چینج نوشتم
circularProgress1.IsRunning = true;
if (!backgroundWorkerSe.IsBusy)
backgroundWorkerSe.RunWorkerAsync();
و بدون مشکل کار کرد.

ژیار رحیمی
شنبه 24 مهر 1395, 22:46 عصر
شما Invoke رو برای circularProgress1 فراخوانی کردی در صورتی که شما داخل متد SearchWord داری به کنترل هایی که در Thread اصلی ساخته شده تغییرات رو اعمال میکنی

public void SearchWords(string strcm)
{
try
{
OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0 ;Data Source=C:\Users\Daniyal\Documents\Visual Studio 2013\Projects\Dani_ProDic\Dani_ProDic\Dic.mdb");
OleDbDataAdapter da = new OleDbDataAdapter(strcm, con);
da.SelectCommand.Parameters.AddWithValue("@En_Text ", radTextBoxSearch.Text + "%");
DataTable dt = new DataTable();
da.Fill(dt);
Invoke((MethodInvoker) delegate
{
radGridViewWords.DataSource = dt;
radGridViewWords.Columns[0].HeaderText = "کلمه";
radGridViewWords.Columns[1].HeaderText = "معنی";
radGridViewWords.Columns[2].IsVisible = false;
radGridViewWords.Columns[3].IsVisible = false;
textBoxTotalMeans.Text = radGridViewWords.CurrentRow.Cells[2].Value.ToString();
});

}
catch (Exception e)
{
MessageBox.Show(e.Message);
}

}

Mahmoud.Afrad
شنبه 24 مهر 1395, 23:38 عصر
همه کدهای مربوط به لود رکورد از دیتا بیس و غیر فعال کردن کنترول circularProgress رو بردم توی رویداد RunWorkerCompleted و توی رویداد DoWork هیچی ننوشتم و فقط توی رویداد تکست چینج نوشتم
circularProgress1.IsRunning = true;
if (!backgroundWorkerSe.IsBusy)
backgroundWorkerSe.RunWorkerAsync();
و بدون مشکل کار کرد.

یعنی اصلا هیچی توی متد DoWork ننوشتید؟!!! خب در اینصورت اصلا backgroundworker چه استفاده ای داره؟

daniyaltjm
یک شنبه 25 مهر 1395, 00:12 صبح
یعنی اصلا هیچی توی متد DoWork ننوشتید؟!!! خب در اینصورت اصلا backgroundworker چه استفاده ای داره؟

آره درسته هیچ استفاده ای از قابلیت تررد نکردم فقط باهاش نحوه نمایش circularProgress رو کنترول کردم ولی با نکته ای که آقای ژیار گفتن و کدی که نوشتن حتما مشکل حل باید بشه :لبخندساده: