PDA

View Full Version : کند بودن زیاد در هنگام بالا آمدن برنامه



harani
چهارشنبه 30 اسفند 1391, 21:50 عصر
با سلام دوستان من یک من تو برنامم از یک دیتابیس دیکشنری Access با حجم 11 M استفاده کرد. من در form_load محتویات اون در یک datagridview ریخته میریزم به نظر شما چرا من زمانیکه برنامه رو اجرا میکنم خیلی طول میکشه بالا بیاد ؟؟ آیا مشکل از Access و استفاده نکردن از sql است یا جای دیگه مشکل داره

اینم کدمه :


private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'dataDataSet.Words' table. You can move, or remove it, as needed.
connect = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Data.mdb");//a

connect.Open();//b
com = new OleDbCommand("select * from words", connect);//b
com.Connection = connect;//c
oleDbDataAdapter1.Fill(dataDataSet1);//d
dataGridView1.DataSource = dataDataSet1.Tables[0];//e
connect.Close();//f


}



لطفاً راهنمایی فرمایید با سپاس

C#‎_best_Programmer
چهارشنبه 30 اسفند 1391, 22:09 عصر
دادشم اولا اینکه یه کار اشتباهت در مورد بستن کانکشن چون که فک کن قبل اینکه کانکشن کلوز شه یه استثنا پیش بیاد اون موقع کانکشن اوپن میمونه بعد اینکه آیا از کمپوننت استفاده کردی؟

veniz2008
چهارشنبه 30 اسفند 1391, 22:24 عصر
دادشم اولا اینکه یه کار اشتباهت در مورد بستن کانکشن چون که فک کن قبل اینکه کانکشن کلوز شه یه استثنا پیش بیاد اون موقع کانکشن اوپن میمونه بعد اینکه آیا از کمپوننت استفاده کردی؟
سلام.
دوست عزیز شی Adapter یک شی غیر اتصال گراست بنابراین نیازی اصلا به باز کردن کانکشن نداره.


با سلام دوستان من یک من تو برنامم از یک دیتابیس دیکشنری Access با حجم 11 M استفاده کرد. من در form_load محتویات اون در یک datagridview ریخته میریزم به نظر شما چرا من زمانیکه برنامه رو اجرا میکنم خیلی طول میکشه بالا بیاد ؟؟ آیا مشکل از Access و استفاده نکردن از sql است یا جای دیگه مشکل داره

همه چیز بستگی به نوع کدنویسی و میزان داده های شما و سخت افزار شما داره.
چه تعداد رکورد رو در لحظه اول لود می کنید؟
چرا از stored procedure استفاده نمی کنید؟
می تونید از شی datareader استفاده کنید. یه جایی خوندم که ادعا می کرد 30 برابر سرعتش نسبت به دیتاست بیشتره!!
و نکته های مهم:
چرا همه داده ها رو به یکباره لود می کنید؟
و چرا Access ؟
سخت افزار شما (مخصوصا میزان رم سیستم) چه مقدار هست؟
اینم ببین دوست من :
http://barnamenevis.org/showthread.php?204134-%D9%85%D9%82%D8%A7%DB%8C%D8%B3%D9%87-Access-%D9%88-SQL-Server-!%D8%9F&highlight=sql+access

C#‎_best_Programmer
چهارشنبه 30 اسفند 1391, 22:28 عصر
نه دادشم آداپتر جزو اشیای متصل خیلی ساده یه بار تست کن ببین میتونی امتحان کنی:قلب:

veniz2008
چهارشنبه 30 اسفند 1391, 22:55 عصر
نه دادشم آداپتر جزو اشیای متصل خیلی ساده یه بار تست کن ببین میتونی امتحان کنی:قلب:
شی دیتا ست و دیتاتیبل که همرا Adapter بکار میرن غیر اتصال گرا هستند و شی DataReader اتصال گراست.
لطفا اول مطالعه کنید . اینا رو ببین دوست عزیز :
http://barnamenevis.org/showthread.php?92344-%D8%AA%D9%81%D8%A7%D9%88%D8%AA-%D8%A8%DB%8C%D9%86-IDbConnection-%D9%88-SqlConnection&highlight=%D8%AA%D9%81%D8%A7%D9%88%D8%AA+%D8%A8%DB %8C%D9%86+IDbConnection+SqlConnection
یا
http://barnamenevis.org/showthread.php?122584-%DA%86%D8%B1%D8%A7-DataReader-%D9%87%D9%85%D9%8A%D8%B4%D9%87-Close-%D8%A7%D8%B3%D8%AA-%D8%9F&highlight=%DA%86%D8%B1%D8%A7+DataReader+%D9%87%D9% 85%D9%8A%D8%B4%D9%87+Close+%D8%A7%D8%B3%D8%AA

C#‎_best_Programmer
چهارشنبه 30 اسفند 1391, 23:18 عصر
دادشم من جسارت نمی کنم ولی لطفا یه لحظه عملی امتحانش کن لطفا کانکشن و ببند بعد از دیتا آداپتر استفاده کن

harani
چهارشنبه 30 اسفند 1391, 23:22 عصر
دادشم اولا اینکه یه کار اشتباهت در مورد بستن کانکشن چون که فک کن قبل اینکه کانکشن کلوز شه یه استثنا پیش بیاد اون موقع کانکشن اوپن میمونه بعد اینکه آیا از کمپوننت استفاده کردی؟ ن من کاری به این موضوع ندارم اونو که با یه try - catch درست میکنم . مشکل دیر بالا اومونه .


سلام.
دوست عزیز شی Adapter یک شی غیر اتصال گراست بنابراین نیازی اصلا به باز کردن کانکشن نداره.


همه چیز بستگی به نوع کدنویسی و میزان داده های شما و سخت افزار شما داره.
چه تعداد رکورد رو در لحظه اول لود می کنید؟ دو تا ستون که تعداد داده های هر ستون 50129 عدد است .
چرا از stored procedure استفاده نمی کنید؟ فکر نکنم این ویژگی رو Access داشته باشه
می تونید از شی datareader استفاده کنید. یه جایی خوندم که ادعا می کرد 30 برابر سرعتش نسبت به دیتاست بیشتره!! datareder کار نکردم من بدلیل مشکلاتی ، زیاد با دیتابیس نتونستم کار کنم لطفاً اگه این راه حل مناسبی است راهنمایی فرمایید
و نکته های مهم:
چرا همه داده ها رو به یکباره لود می کنید؟ میخوام تمام داده هامو در هنگام بالا آمدن برنامه به کاربر نشون بدم
و چرا Access ؟ این دیتابیس دیکشنری که با هزار بدبختی از اینترنت گیرش اوردم که حالا Access هستش دیگه همچنین با نصب اس کیو ال مشکل پیدا کردم زمانیکه نصب میخواد بکنه از ویژوال ایراد میگیره در ضمن من فقط میخوام از دیتابیس تو برنامه نویسی استفاده کنم نیازی به خود نرم افزارش ندارم نصبش حجم زیادیو میگیره به همین دلایل اکسسو انتخاب کردم
سخت افزار شما (مخصوصا میزان رم سیستم) چه مقدار هست؟ رم من 4 G است
اینم ببین دوست من :
http://barnamenevis.org/showthread.php?204134-%D9%85%D9%82%D8%A7%DB%8C%D8%B3%D9%87-Access-%D9%88-SQL-Server-!%D8%9F&highlight=sql+access

C#‎_best_Programmer
چهارشنبه 30 اسفند 1391, 23:26 عصر
ونیز شرمنده من اشتباه می کردم شرمنده تو کتابی که من خوندم جز متصلا زده بود

veniz2008
چهارشنبه 30 اسفند 1391, 23:35 عصر
ن من کاری به این موضوع ندارم اونو که با یه try - catch درست میکنم . مشکل دیر بالا اومونه .
شما به سوالات من جواب ندادید.
مثلا فرض کن رم سیستم شما 512 باشه. خوب کلی از رم میره صرف خود ویندوز و ویژوال میشه. حالا موقع خوندن از sql بخشی هم اونجا مصرف میشه و اصل مطلب هم شی دیتاست هست که این شی درون رم قرار میگیره . بنابراین در تعداد رکوردهای زیاد با رم کم به مشکل برمیخورید مگر اینکه مدیریتش کنید و همه رکوردها رو یکجا لود نکنید.
سوالات رو جواب بده تا بهتر بشه راهنمایی کرد.

harani
پنج شنبه 01 فروردین 1392, 00:07 صبح
من که تو نقل و قول به شما پاسخ دادم که رمم 4 G هست همه ی 50219 (برای دو ستون) رو میخوام با بالا اومون برنامه به کاربر نشون داده بشه امیدوارم کمکم کنید . با سپاس

veniz2008
پنج شنبه 01 فروردین 1392, 01:47 صبح
ابتدا با روش دیتاریدر تست کنید (من با sql تست کردم، شما با oledb بنویس):

SqlConnection con = new SqlConnection("server = .\\md2008;database = Test1;Integrated Security = True");
SqlCommand cmd = new SqlCommand("select * from TblUser", con);
SqlDataReader reader;
con.Open();
reader = cmd.ExecuteReader();
dt.Load(reader);
dataGridView1.DataSource = dt;
con.Close();
اگر صفحه موقع لود شدن حالت پرش داره میتونید خاصیت DoubleBuffered مربوط به فرم رو هم True کنید.
اگر باز هم مشکل پابرجا بود بگید تا با استقاده از Backgroundworker توضیح بدم.

harani
پنج شنبه 01 فروردین 1392, 10:09 صبح
این کد برای دیتابیس اکسس جواب نداد و برنامه دیر بالا میاد .

veniz2008
پنج شنبه 01 فروردین 1392, 10:53 صبح
خوب حالا با backgrounworker تست کن. یک شی بک گراند ورکر از تولباکس اضافه کن. این شی برای انجام دادن روان فعالیت های سنگین استفاده میشه.
دو تا رویداد مهم داره. یکی DoWork که عملیات اصلی برنامه در این رویداد انجام میشه ویکی هم RunWorkerComplete که موقعیکه عملیات اصلی انجام میشه (صحیح یا اشتباه) این رویداد نقش خودش رو ایفا میکنه. طبق کد زیر انجام بدید(راستی کانکشن استرینگ و دیتاتیبل رو بصورت عمومی در Partial تعریف کنید):
رویداد DoWork :

con = new SqlConnection("server = .\\md2008;database = Test1;Integrated Security = True");
SqlCommand cmd = new SqlCommand("select * from TblUser", con);
SqlDataReader reader;
dt = new DataTable();
con.Open();
reader = cmd.ExecuteReader();
dt.Load(reader);
رویداد RunWorkerCompleted (اول چک میکنم که آیا در روند اجرایی کار خطایی رخ داده یا نه. اگر خطایی رخ نداده بود،گرید رو پر میکنم و کانکشن رو می بندم):

if (e.Error == null)
{
dataGridView1.DataSource = dt;
con.Close();
}
else
{
MessageBox.Show("در بارگذاری اطلاعات مشکلی بوجود آمد. لطفا مجددا اقدام کنید");
}
حالا در formload کد زیر رو بنویسید :

if (!backgroundWorker1.IsBusy)
backgroundWorker1.RunWorkerAsync();
اگر فرم موقع لود شدن بخاطر تعداد زیاد داده ها حالت پرش و قطع و وصل شدن داره حتما خاصیت DoubleBufferd رو True کنید.
اگر باز هم جواب نگرفتید، دیتابیس رو بذارید تا روی سیستم خودم چک کنم(ولی تعجب من اینه که این تعداد رکورد اصلا تعدادی نیست که بخواد سنگین اجرا بشه).

tooraj_azizi_1035
پنج شنبه 01 فروردین 1392, 15:19 عصر
مدت زمان خواندن داده ها با دستور SELECT رو نمی تونید کاهش دهید باید رویکرد Async رو در پیش بگیرید تا برنامه تون قفل نکنه.
متد های BeginExecuteReader و EndExecuteReader رو برای همین کار ساختند:


using System.Data.SqlClient;

namespace Microsoft.AdoDotNet.CodeSamples
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

// Hook up the form's Load event handler (you can double-click on
// the form's design surface in Visual Studio), and then add
// this code to the form's class:

// You need this delegate in order to fill the grid from
// a thread other than the form's thread. See the HandleCallback
// procedure for more information.
private delegate void FillGridDelegate(SqlDataReader reader);

// You need this delegate to update the status bar.
private delegate void DisplayStatusDelegate(string Text);

// This flag ensures that the user does not attempt
// to restart the command or close the form while the
// asynchronous command is executing.
private bool isExecuting = false;

// Because the overloaded version of BeginExecuteReader
// demonstrated here does not allow you to have the connection
// closed automatically, this example maintains the
// connection object externally, so that it is available for closing.
private SqlConnection connection = null;

private void DisplayStatus(string Text)
{
this.label1.Text = Text;
}

private void FillGrid(SqlDataReader reader)
{
try
{
DataTable table = new DataTable();
table.Load(reader);
this.dataGridView1.DataSource = table;
DisplayStatus("Ready");
}
catch (Exception ex)
{
// Because you are guaranteed this procedure
// is running from within the form's thread,
// it can directly interact with members of the form.
DisplayStatus(string.Format("Ready (last attempt failed: {0})",
ex.Message));
}
finally
{
// Do not forget to close the connection, as well.
if (reader != null)
{
reader.Close();
}
if (connection != null)
{
connection.Close();
}
}
}

private void HandleCallback(IAsyncResult result)
{
try
{
// Retrieve the original command object, passed
// to this procedure in the AsyncState property
// of the IAsyncResult parameter.
SqlCommand command = (SqlCommand)result.AsyncState;
SqlDataReader reader = command.EndExecuteReader(result);
// You may not interact with the form and its contents
// from a different thread, and this callback procedure
// is all but guaranteed to be running from a different thread
// than the form. Therefore you cannot simply call code that
// fills the grid, like this:
// FillGrid(reader);
// Instead, you must call the procedure from the form's thread.
// One simple way to accomplish this is to call the Invoke
// method of the form, which calls the delegate you supply
// from the form's thread.
FillGridDelegate del = new FillGridDelegate(FillGrid);
this.Invoke(del, reader);
// Do not close the reader here, because it is being used in
// a separate thread. Instead, have the procedure you have
// called close the reader once it is done with it.
}
catch (Exception ex)
{
// Because you are now running code in a separate thread,
// if you do not handle the exception here, none of your other
// code catches the exception. Because there is none of
// your code on the call stack in this thread, there is nothing
// higher up the stack to catch the exception if you do not
// handle it here. You can either log the exception or
// invoke a delegate (as in the non-error case in this
// example) to display the error on the form. In no case
// can you simply display the error without executing a delegate
// as in the try block here.
// You can create the delegate instance as you
// invoke it, like this:
this.Invoke(new DisplayStatusDelegate(DisplayStatus),
"Error: " + ex.Message);
}
finally
{
isExecuting = false;
}
}

private string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.

// If you do not include the Asynchronous Processing=true name/value pair,
// you wo not be able to execute the command asynchronously.
return "Data Source=(local);Integrated Security=true;" +
"Initial Catalog=AdventureWorks; Asynchronous Processing=true";
}

private void button1_Click(object sender, System.EventArgs e)
{
if (isExecuting)
{
MessageBox.Show(this,
"Already executing. Please wait until the current query " +
"has completed.");
}
else
{
SqlCommand command = null;
try
{
DisplayStatus("Connecting...");
connection = new SqlConnection(GetConnectionString());
// To emulate a long-running query, wait for
// a few seconds before retrieving the real data.
command = new SqlCommand("WAITFOR DELAY '0:0:5';" +
"SELECT ProductID, Name, ListPrice, Weight FROM Production.Product",
connection);
connection.Open();

DisplayStatus("Executing...");
isExecuting = true;
// Although it is not required that you pass the
// SqlCommand object as the second parameter in the
// BeginExecuteReader call, doing so makes it easier
// to call EndExecuteReader in the callback procedure.
AsyncCallback callback = new AsyncCallback(HandleCallback);
command.BeginExecuteReader(callback, command);
}
catch (Exception ex)
{
DisplayStatus("Error: " + ex.Message);
if (connection != null)
{
connection.Close();
}
}
}
}

private void Form1_Load(object sender, System.EventArgs e)
{
this.button1.Click += new System.EventHandler(this.button1_Click);
this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
}

void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (isExecuting)
{
MessageBox.Show(this, "Cannot close the form until " +
"the pending asynchronous command has completed. Please wait...");
e.Cancel = true;
}
}
}
}

harani
جمعه 02 فروردین 1392, 01:24 صبح
یه سوال تو کد زیر:



con = new SqlConnection("server = .\\md2008;database = Test1;Integrated Security = True");
SqlCommand cmd = new SqlCommand("select * from TblUser", con);
SqlDataReader reader;
dt = new DataTable();
con.Open();
reader = cmd.ExecuteReader();
dt.Load(reader);


من اگه بتونم به جای cmd از DataView استفاده کنم مشکلم حل میشه چگونه اینکار ممکن است ؟؟

veniz2008
جمعه 02 فروردین 1392, 01:50 صبح
من اگه بتونم به جای cmd از DataView استفاده کنم مشکلم حل میشه چگونه اینکار ممکن است ؟؟
مشکل شما از این چیزها نیست و باید دلیل کند بودن برنامتون رو مشخص کنید. من 100 هزار رکورد رو در 1 ثانیه درون گرید لود میکنم. تعجب میکنم چطور شما با 50 هزار رکورد مشکل داری و برنامتون کنده. اگر امکانش هست دیتابیس برنامتون رو بذارید تا با سیستم خودم چکش کنم.

harani
جمعه 02 فروردین 1392, 14:27 عصر
اینم دیتابیس http://bayanbox.ir/user/nevercom/archives/Data.mdb.7z

ali_habibi1384
جمعه 02 فروردین 1392, 14:45 عصر
خيلي تابلويه. چون واسه خوندن از DataAdapter استفاده كردي. اين ريدر موقع خوندن و پر كردن ديتا تيبل پروسه رو متوقف ميكنه . ازDataReader استفاده كنيد.

veniz2008
جمعه 02 فروردین 1392, 15:08 عصر
نتیجه استفاده رو میتونید در ویدئوی زیر ببینید (با Adapter واستون تست کردم و برخلاف انتظار دیدم که نتیجه بهتری رو نسبت به DataReader میده!!) .

ali_habibi1384
جمعه 02 فروردین 1392, 15:15 عصر
وقتي از DataReader استفاده ميكني بايد مثلا 50تا 50 تا لود كني نه اينكه همه رو باهم بريزي.
ديتا ريدر روشي براي بارگذاري فايلهاي حجيم هست.من نميدونم شما چطور كد نوشتي

veniz2008
جمعه 02 فروردین 1392, 16:55 عصر
منظورتون از 50 تا 50 تا همون paging کردن گرید هست؟. اگر منظورتون اینه که ظاهرا دوستمون نمیخوان چنین کاری رو انجام بدن و هدفشون اینه که همه رکوردها رو در همون صفحه اصلی نشون بدن!.
اگر هم منظورتون مورد دیگه ای هست بیشتر در موردش توضیح بدید.

ali_habibi1384
جمعه 02 فروردین 1392, 19:22 عصر
گفتم شايد ندونيد Paging چيه زبان ساده تر گفتم.بله منظورم همونه.
دوست عزيز وقتي برنامه باز ميشه كاربر در همون ثانيه اول نميتونه كل50.000 ركورد رو باهم ببينه پس شما توي ترد يا تايمر كم كم اطلاعات رو توي گريد لود ميكني بطوريكه كاربر متوجه نميشه.
اگر فيس بوك سر زده باشيد دقيقا همين كارو ميكنه.كل اطلاعات جديد رو باهم لود نميكنه اون مقداري كه كاربر ميتونه همون اول ببينه لود ميكنه و كم كم بقيه رو بارگذاري ميكنه.حالا اينكه كسي ميخواد روش جديدي از خودش بسازه نميدونم.
بنظرم كاري رو از پيكان ميخوايد بكشيد كه مثلا زانتيا قراره انجام بده.خب دوست عزيز نشدنيست.

veniz2008
جمعه 02 فروردین 1392, 19:31 عصر
گفتم شايد ندونيد Paging چيه زبان ساده تر گفتم.بله منظورم همونه.
نظر لطف شماست.

دوست عزيز وقتي برنامه باز ميشه كاربر در همون ثانيه اول نميتونه كل50.000 ركورد رو باهم ببينه پس شما توي ترد يا تايمر كم كم اطلاعات رو توي گريد لود ميكني بطوريكه كاربر متوجه نميشه.
اگر فيس بوك سر زده باشيد دقيقا همين كارو ميكنه.كل اطلاعات جديد رو باهم لود نميكنه اون مقداري كه كاربر ميتونه همون اول ببينه لود ميكنه و كم كم بقيه رو بارگذاري ميكنه.حالا اينكه كسي ميخواد روش جديدي از خودش بسازه نميدونم.
بنظرم كاري رو از پيكان ميخوايد بكشيد كه مثلا زانتيا قراره انجام بده.خب دوست عزيز نشدنيست.
لود کردن تمام رکوردها در لحظه اولیه استراتژی من نیست و اگر پست 3 بنده رو خوب مطالعه می کردید متوجه میشدید که من خودم این سوال رو از ایجاد کننده تاپیک پرسیدم که چرا همه اطلاعات رو به یکباره لود میکنه ولی همونطور که در پست های قبلی هم گفتم دوستمون (به هر دلیلی که واسه خودش محترمه) قصد داره همه اطلاعات رو در همون لحظه اولیه و بدون استفاده از paging لود کنه و گرنه من خودم در چنین حالاتی حتما از paging استفاده می کنم. که راه اصولیش هم همینه و کاربر به یکباره 50 هزار رکورد به دردش نمیخوره!

ali_habibi1384
جمعه 02 فروردین 1392, 19:52 عصر
نظر لطف شماست.

لود کردن تمام رکوردها در لحظه اولیه استراتژی من نیست و اگر پست 3 بنده رو خوب مطالعه می کردید متوجه میشدید که من خودم این سوال رو از ایجاد کننده تاپیک پرسیدم که چرا همه اطلاعات رو به یکباره لود میکنه ولی همونطور که در پست های قبلی هم گفتم دوستمون (به هر دلیلی که واسه خودش محترمه) قصد داره همه اطلاعات رو در همون لحظه اولیه و بدون استفاده از paging لود کنه و گرنه من خودم در چنین حالاتی حتما از paging استفاده می کنم. که راه اصولیش هم همینه و کاربر به یکباره 50 هزار رکورد به دردش نمیخوره!
دوست عزيز منظور حرف من هم شما نبوديد.سوء تفاهم نباشه.
منظور من اوني هست كه هنوز با اكسس كار ميكنه فرق موارد استفاده Adapter , Reader رو نميدونه و بر يك باور غلط ميخواد همه باورش رو بسازه!
دليل اينكه توي اين بحث شركت كردم اين نبود كه فقط پاسخ صاحب تاپيك رو بدم برعكس فقط ميخواستم بقيه يه چيزي ياد بگيرند.