PDA

View Full Version : استفاده از backgroundworker در اتصال به sql



sajjadrad
جمعه 13 اسفند 1389, 20:07 عصر
سلام دوستان
من تالار رو به دقت جستجو کردم اما چیزی پیدا نکردم...
من یه دیتابیس دارم که میخوام در زمان insert,select,update,delete از backgroundworker برای نمایش یک پنجره "لطفا صبر کنید" استفاده کنم تا برنامه در هنگام کوئری گرفتن هنگ نکنه...
مثلا برای کوئری select در رویداد DoWork از کد زیر استفاده کردم:


SqlConnection con = new SqlConnection();
con.ConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirector y|\Database.mdf;Integrated Security=True;User Instance=True";
con.Open();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = new SqlCommand();
da.SelectCommand.Connection = con;
da.SelectCommand.CommandType = CommandType.Text;
da.SelectCommand.CommandText = "select ID,af_fname af where arch=0 ";
dt = new DataTable();
da.Fill(dt);
con.Close();
DataView view1 = new DataView(dt);
CurrencyManager cur;
cur = (CurrencyManager)(this.BindingContext[view1]);
e.Result = cur;
e.Result = dt;

و کد زیر در رویداد Completed:



var dt = e.Result as DataTable;
var cur = e.Result as CurrencyManager;
if (cur.Count == 0)
{
dataGridView1.DataSource = dt;
MessageBox.Show("Not found", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
dataGridView1.DataSource = dt;
}





اما خطا زیر رو داد:

Exception has been thrown by the target of an invocation.

---------
البته من در کوئری های دیگه مشکل دارم...چون اونجا cur یا dt ندارم که بتونم در completed ازش استفاده کنم...

در ضمن بعضی از دوستان پروژه waitWindows رو گذاشتن اما هرکاری کردم نتونستم ازش استفاده کنم....
پروژه رو اتچ میکنم

مرسی

morteza271
جمعه 13 اسفند 1389, 20:45 عصر
من قبلا یه برنامه نوشتم که اطلاعات رو از یه جدول به یکی دیگه انتقال میداد و همزمان یه پروگرس بار رو پر میکرد شاید براتون خوب باشه.
براتون میذارم اگه تونستین ازش استفاده کنین.
البته خود برنامه رو نتونستم بذارم(هر کاری کردم آپلود نشد!)
به همین خاطر کدشو براتون میذارم:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Threading;
using FarsiMessageBox;

namespace thread_test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

Thread t1;
//Thread t_showform2;

int count = 0;
float f = 0;
bool pb_visible = false;

private void btnMoveData_Click(object sender, EventArgs e)
{
//MyThread.Move_Data();

t1 = new Thread(new ThreadStart(Move_Data));
//t2 = new Thread(new ThreadStart(ProgressBar));

pb_visible = true;

t1.Start();
//t2.Start();
}

public void Move_Data()
{
int row_count = 0;

//string strconn_dbcanservices = @"Data Source=" + "VAHID-PC" + "\\MSSQLEXPRESS;" + "Initial Catalog=db_canservices;Integrated Security=true;User Id=canservices1;Password=canservices";
string strconn_dthread = @"Data Source=" + "VAHID-PC" + "\\MSSQLEXPRESS;" + "Initial Catalog=db_thread;Integrated Security=true";

//SqlConnection sqlconn1 = new SqlConnection(strconn_dbcanservices);
SqlConnection sqlconn2 = new SqlConnection(strconn_dthread);
string qry_read = @"select name,phonehome,mobile,address from Person";
string qry_write = @"insert into Customer(name,phonehome,mobile,address,city,number ) values(@name,@phonehome,@mobile,@address,@city,@nu mber)";

try
{
SqlCommand cmdqry1 = new SqlCommand(qry_read, sqlconn2);

SqlDataAdapter da = new SqlDataAdapter(cmdqry1);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
row_count = dt.Rows.Count;
int i = 0;
foreach (DataRow row in dt.Rows)
{
SqlCommand cmdqry2 = new SqlCommand(qry_write, sqlconn2);
cmdqry2.Parameters.AddWithValue(@"name", row[0].ToString());
cmdqry2.Parameters.AddWithValue(@"phonehome", row[1].ToString());
cmdqry2.Parameters.AddWithValue(@"mobile", row[2].ToString());
cmdqry2.Parameters.AddWithValue(@"address", row[3].ToString());
cmdqry2.Parameters.AddWithValue(@"city", "مشهد");
cmdqry2.Parameters.AddWithValue(@"number", dt.Rows.Count);
sqlconn2.Open();
cmdqry2.ExecuteNonQuery();
sqlconn2.Close();
i++;
//f = i % 100;
f = (float)i / (float)row_count;
f = f * 100;
}
MessageBox.Show("Move");
pb_visible = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return;
}
}

private void ProgressBar()
{
for (int i = 0; i <= 9000000; i++)
{
if (i == 3000000)
{
if (count < 100)
count += 1;
i = 0;
}
}
}

private void timer1_Tick(object sender, EventArgs e)
{
textBox2.Text = f.ToString();
progressBar1.Visible = pb_visible;
progressBar1.Value = (int)f;
}

private void Show_From2()
{
Form2 frmform2 = new Form2();
frmform2.ShowDialog();
}

public fclsLoading frmLoad;
bool load = true;

private void btnShowForm2_Click(object sender, EventArgs e)
{
load = true;
backgroundWorker1.RunWorkerAsync();
frmLoad = new fclsLoading();
frmLoad.ShowDialog();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Form2 frmform2 = new Form2();

frmform2.employeesTableAdapter.Fill(frmform2.db_ca nserviceDataSet.Employees);
frmform2.bug_reportTableAdapter.Fill(frmform2.db_c anserviceDataSet.Bug_report);
frmform2.archiveServiceTableAdapter.Fill(frmform2. db_canserviceDataSet.ArchiveService);
frmform2.waitServiceTableAdapter.Fill(frmform2.db_ canserviceDataSet.WaitService);

// move data...
string strconn_dbcanservices = @"Data Source=" + "VAHID-PC" + "\\MSSQLEXPRESS;" + "Initial Catalog=db_thread;Integrated Security=true";
string strconn_dthread = @"Data Source=" + "VAHID-PC" + "\\MSSQLEXPRESS;" + "Initial Catalog=db_thread;Integrated Security=true";

SqlConnection sqlconn1 = new SqlConnection(strconn_dbcanservices);
SqlConnection sqlconn2 = new SqlConnection(strconn_dthread);
string qry_read = @"select name,phonehome,mobile,address from Person";
string qry_write = @"insert into Customer(name,phonehome,mobile,address,city,number ) values(@name,@phonehome,@mobile,@address,@city,@nu mber)";

try
{
SqlCommand cmdqry1 = new SqlCommand(qry_read, sqlconn1);

SqlDataAdapter da = new SqlDataAdapter(cmdqry1);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
sqlconn2.Open();
foreach (DataRow row in dt.Rows)
{
SqlCommand cmdqry2 = new SqlCommand(qry_write, sqlconn2);
cmdqry2.Parameters.AddWithValue(@"name", row[0].ToString());
cmdqry2.Parameters.AddWithValue(@"phonehome", row[1].ToString());
cmdqry2.Parameters.AddWithValue(@"mobile", row[2].ToString());
cmdqry2.Parameters.AddWithValue(@"address", row[3].ToString());
cmdqry2.Parameters.AddWithValue(@"city", "مشهد");
cmdqry2.Parameters.AddWithValue(@"number", dt.Rows.Count);

cmdqry2.ExecuteNonQuery();
}
sqlconn2.Close();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return;
}

load = false;
frmform2.ShowDialog();
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (frmLoad != null && frmLoad.Visible)
frmLoad.Dispose();
}

private void timer2_Tick(object sender, EventArgs e)
{
if (frmLoad != null && frmLoad.Visible && load == false)
frmLoad.Dispose();
}
}
}

sajjadrad
جمعه 13 اسفند 1389, 21:31 عصر
مرسی دوست عزیز بابت پاسخ
اگه میشه این پروژه رو یجایی اپلود کنید که من بتونم ببینم اینجوری خیلی گیج شدم:لبخند:
شرمنده...رپیدشیر یا یه سروری اگه زحمت نیست آپلود کنید...

بعد یه سوال دیگه اینکه من میتونم اطلاعات رو از داخل textbox یا combobox و یا متغیر در داخل رویداد DoWork بگیرم؟

morteza271
جمعه 13 اسفند 1389, 21:50 عصر
شرمنده هر کاری میکنم نمیشه!!!:گریه:

اگه میشه میلتونو بدین تا بفرستم.

sajjadrad
جمعه 13 اسفند 1389, 22:47 عصر
واستون تو پیغام خصوصی فرستادم...
مرسی
لطفا اگه میشه به اون سوالات هم پاسخ بدید:لبخند:

sajjadrad
شنبه 14 اسفند 1389, 12:48 عصر
پروژه شما رو به دقت بررسی کردم...
مشکلم در کوئری select حل شد...الان میخوام یه فرم Please Wait بذارم...فرم رو طراحی کنم..
زمانی که تابع DoWork رو فراخوانی کردم زیرش فرم waiting رو showdialog کردم که بصورت tread باز شه...اما بعد از کامل شدن در رویداد Completed نمیتونم فرم waiting رو ببندم....
خب چون شی فرم در یه متد دیگه ساخته و باز شده و قابل دسترسی از یه متد دیگه نیست...در پروژه شما از این کد استفاده کردید:

public fclsLoading frmLoad;
و بعد frmload رو ساختید و showdialog کردید و در completed اونو بستید...
من چطور میتونم در رویداد completed فرمی که در متد دیگه ساخته شده رو ببندم؟


backgroundWorker1.RunWorkerAsync();
waiting wait = newwaiting();
wait.ShowDialog();

باتشکر

در ضمن من وقتی میخوام اطلاعات رو insert کنم مقادیر عددی رو از combobox میگیرم و به int32 تبدیل میکنم...اما مثله اینکه نمیشه از اشیای tread دیگه استفاده کرد و با خطای زیر مواجه شدم:



Cross-thread operation not valid: Control 'combo1' accessed from a thread other than the thread it was created on.


چطور میتونم اطلاعات رو به DoWork بفرستم؟

morteza271
شنبه 14 اسفند 1389, 14:13 عصر
در مورد بستن فرم نمیدونم!
ولی برای استفاده از مقداری که داخل ComboBox انتخاب شده میتونید مقدارشو داخل یه متغیر عمومی بذارید و ازش در هرجا که خواستین استفاده کنید.
موفق باشید

sajjadrad
شنبه 14 اسفند 1389, 14:32 عصر
خیلی ممنون
انتقال اطلاعات رو درست کردم
اما الان مشکلم سر بستن فرم صبر کنیده:ناراحت:

morteza271
شنبه 14 اسفند 1389, 14:47 عصر
اینجوری نمیشه :

یه متغیر تعریف کنید و در زمانی که فرم صبر کنید رو نمایش میدید اون متغیر رو مقدار بدین(مثلا true)
حالا وقتی میخواین اون فرم رو ببندین اون متغیر رو false کنید.
و با یه تایمر یا یه جور دیگه بگین وقتی که اون متغیر fasle هست اون فرم رو ببنده یا visible رو fasle کنه.

sajjadrad
شنبه 14 اسفند 1389, 23:12 عصر
این کارو کردم جواب داد اما گذاشتن تایمر یه پردازش اضافست:ناراحت:

morteza271
یک شنبه 15 اسفند 1389, 14:17 عصر
دیگه چیزی به نظرم نمیرسه!
ولی برای اینکه همیشه تایمر کار نکنه میتونید وقتی فرم رو نشون میدین تایمر رو استارت کنین و وقتی فرم رو بستین تایمر رو هم استوپ کنین.
موفق باشید.