PDA

View Full Version : خطا در thread



qasemf
شنبه 18 بهمن 1399, 15:09 عصر
سلام
میخوام اطلاعات و دیتای داخل کلیپ برد رو داخل لیست ویو نمایش بدم و بعد اطلاعات از لیست ویو خونده بشه و انتقال فایل انجام بشه تا در صورت لزوم بتونم مثلا یه ایتم رو حذف کنم و از صف انتقال delete کنم یعنی حتی زمانی که انتقال فایل در thread در حال انجام هست و thread در حال اجرا هست شاید بخوام یه ایتم رو حذف کنم مطمئنا باید از delegate استفاده کرد اما نمیدونم چطوری!!! چون فعلا این پیغام رو میده
Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on [duplicate] (https://stackoverflow.com/questions/10775367/cross-thread-operation-not-valid-control-textbox1-accessed-from-a-thread-othe)

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{




// list_of_file.Invoke.(new UpdateUIDelegate(Updatereplist));
var dest = Path.GetFullPath(txt_usercontrol.Text ");
var list = new List<KeyValuePair<string, string>>();
foreach (object item in list_of_file.Items)
{


list.Add(new KeyValuePair<string, string>(item.ToString(), dest));
}

for (var i = 0; i < list.Count; i++)

{
if (Directory.Exists(list[i].Key))
{
var destFolder = Path.Combine(list[i].Value, Path.GetFileName(list[i].Key));
if (Directory.Exists(destFolder) == false)
{
Directory.CreateDirectory(destFolder);
}
foreach (var file in Directory.GetFiles(list[i].Key))
{

list.Add(new KeyValuePair<string, string>(file, destFolder));


}
foreach (var folder in Directory.GetDirectories(list[i].Key))
{
list.Add(new KeyValuePair<string, string>(folder, destFolder));
}
}
else if (File.Exists(list[i].Key))
{

var destFile = Path.Combine(list[i].Value, Path.GetFileName(list[i].Key));
Copy(list[i].Key, destFile);
}

}
}

the king
شنبه 18 بهمن 1399, 15:57 عصر
سلام
میخوام اطلاعات و دیتای داخل کلیپ برد رو داخل لیست ویو نمایش بدم و بعد اطلاعات از لیست ویو خونده بشه و انتقال فایل انجام بشه تا در صورت لزوم بتونم مثلا یه ایتم رو حذف کنم و از صف انتقال delete کنم یعنی حتی زمانی که انتقال فایل در thread در حال انجام هست و thread در حال اجرا هست شاید بخوام یه ایتم رو حذف کنم مطمئنا باید از delegate استفاده کرد اما نمیدونم چطوری!!! چون فعلا این پیغام رو میده
Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on [duplicate] (https://stackoverflow.com/questions/10775367/cross-thread-operation-not-valid-control-textbox1-accessed-from-a-thread-othe)



private void Worker_DoWork(object sender, DoWorkEventArgs e)
{




// list_of_file.Invoke.(new UpdateUIDelegate(Updatereplist));
var dest = Path.GetFullPath(txt_usercontrol.Text ");
var list = new List<KeyValuePair<string, string>>();
foreach (object item in list_of_file.Items)
{


list.Add(new KeyValuePair<string, string>(item.ToString(), dest));
}

for (var i = 0; i < list.Count; i++)

{
if (Directory.Exists(list[i].Key))
{
var destFolder = Path.Combine(list[i].Value, Path.GetFileName(list[i].Key));
if (Directory.Exists(destFolder) == false)
{
Directory.CreateDirectory(destFolder);
}
foreach (var file in Directory.GetFiles(list[i].Key))
{

list.Add(new KeyValuePair<string, string>(file, destFolder));


}
foreach (var folder in Directory.GetDirectories(list[i].Key))
{
list.Add(new KeyValuePair<string, string>(folder, destFolder));
}
}
else if (File.Exists(list[i].Key))
{

var destFile = Path.Combine(list[i].Value, Path.GetFileName(list[i].Key));
Copy(list[i].Key, destFile);
}

}
}


فرض کنیم که یک textBox1.Text ای هست که در نخی که Worker_DoWork رو فراخوانی می کنه مقدارش رو می خواهید تغییر بدهید.

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
textBox1.Text = "test";
}

که دسترسی با خطا روبرو میشه.
و با Invoke میشه انجامش رو به نخ اصلی واگذار کرد :

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
SetText(textBox1, "test");
}

private delegate void SetTextDelegate(Control ctl, string text);

private void SetText(Control ctl, string text)
{
if (ctl.InvokeRequired)
{
ctl.Invoke(new SetTextDelegate(SetText), ctl, text);
}
else
{
ctl.Text = text;
}
}


یا فرضا یک متدی رو در اجرا می کنید که کاری رو انجام میده که باید حتما در نخ اصلی انجام بشه چون در غیر اینصورت خطای عدم دسترسی رخ میده :

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Updatereplist();
}

private void Updatereplist()
{
textBox1.Text = "test";
}

پس با Invoke اجرایش را به نخ اصلی واگذار می کنید:

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Updatereplist();
}

private void Updatereplist()
{
if (InvokeRequired)
{
Invoke(new UpdatereplistDelegate(Updatereplist));
return;
}
textBox1.Text = "test";
}

private delegate void UpdatereplistDelegate();

qasemf
سه شنبه 21 بهمن 1399, 15:45 عصر
فرض کنیم که یک textBox1.Text ای هست که در نخی که Worker_DoWork رو فراخوانی می کنه مقدارش رو می خواهید تغییر بدهید.

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
textBox1.Text = "test";
}

که دسترسی با خطا روبرو میشه.
و با Invoke میشه انجامش رو به نخ اصلی واگذار کرد :

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
SetText(textBox1, "test");
}

private delegate void SetTextDelegate(Control ctl, string text);

private void SetText(Control ctl, string text)
{
if (ctl.InvokeRequired)
{
ctl.Invoke(new SetTextDelegate(SetText), ctl, text);
}
else
{
ctl.Text = text;
}
}


یا فرضا یک متدی رو در اجرا می کنید که کاری رو انجام میده که باید حتما در نخ اصلی انجام بشه چون در غیر اینصورت خطای عدم دسترسی رخ میده :

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Updatereplist();
}

private void Updatereplist()
{
textBox1.Text = "test";
}

پس با Invoke اجرایش را به نخ اصلی واگذار می کنید:

private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Updatereplist();
}

private void Updatereplist()
{
if (InvokeRequired)
{
Invoke(new UpdatereplistDelegate(Updatereplist));
return;
}
textBox1.Text = "test";
}

private delegate void UpdatereplistDelegate();


خب الان مشکل عدم دسترسی حل شد فقط 2 تا مورد هستش یکی اینکه زمانیکه انتقال فایل میخواد انجام بشه پروگرس بار فقط یه بار پر میشه !! قبلا اطلاعات از stringcollection دریافت میشد اما الان که از لیست ویو خونده میشه این مشکل به وجود اومده و میخوام باز هم مثل قبل هر ایتم که در حال انتقال هست داخل پروگرس بار نمایش داده بشه !!!
مورد بعد هم اینکه کلا ایتم هایی که قرار هست کپی بشن اول داخل لیست ویو نمایش داده میشن و بعد اگر استارت زده بشه انتقال فایل انجام میشه !!حالا در همین حین مثلا اگر خواسته باشیم ایتم سوم حذف بشه چطور باید عمل کرد ؟ نا گفته نماند کدی که نوشتم اینطوری هست که اگر ایتم انتخاب شده حذف شد اون متد Updatereplist() فراخوانی بشه که البته درست عمل نمیکنه!!



private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Updatereplist();

for (int i = 0; i < 100; i++)
{


locker.WaitOne();
Thread.Sleep(100);
worker.ReportProgress(i);


if (worker.CancellationPending)
{
e.Cancel = true;
worker.ReportProgress(0);
return;
}

}

// list_of_file.Invoke.(new UpdateUIDelegate(Updatereplist));

}

private void Updatereplist()
{

if (list_of_file.InvokeRequired)
{
Invoke(new UpdatereplistDelegate(Updatereplist));
return;
}



var dest = Path.GetFullPath(txt_usercontrol.Text + "/" + "HiradMedia");
var list = new List<KeyValuePair<string, string>>();
for (int i = 0; i < list_of_file.Items.Count; i++)
{

// MessageBox.Show(list_of_file.Items[i].Text);
list.Add(new KeyValuePair<string, string>(list_of_file.Items[i].Text, dest));
}
/* foreach (string item in list_of_file.Items)
{

// MessageBox.Show(item.ToString());
list.Add(new KeyValuePair<string, string>(item, dest));

}*/

for (var i = 0; i < list.Count; i++)

{

if (Directory.Exists(list[i].Key))
{
var destFolder = Path.Combine(list[i].Value, Path.GetFileName(list[i].Key));

if (Directory.Exists(destFolder) == false)
{
Directory.CreateDirectory(destFolder);
}
foreach (var file in Directory.GetFiles(list[i].Key))
{

list.Add(new KeyValuePair<string, string>(file, destFolder));


}
foreach (var folder in Directory.GetDirectories(list[i].Key))
{
list.Add(new KeyValuePair<string, string>(folder, destFolder));
}
}
else if (File.Exists(list[i].Key))
{

var destFile = Path.Combine(list[i].Value, Path.GetFileName(list[i].Key));
Copy(list[i].Key, destFile);

}

}



}
private delegate void UpdatereplistDelegate();
private void Copy(string source, string destination)
{
// MessageBox.Show(destination.ToString());

int array_length = (int)Math.Pow(2, 19);
byte[] dataArray = new byte[array_length];
/* using (FileStream fsread = new FileStream
(source, FileMode.Open, FileAccess.Read, FileShare.None, array_length))*/
using (var fsread = File.OpenRead(source))
// using (var fsin = File.OpenRead(source, FileMode.Open, FileAccess.Read, FileShare.None, array_length))
{
using (BinaryReader bwread = new BinaryReader(fsread))
{
using (FileStream fswrite = new FileStream
(destination, FileMode.Create, FileAccess.Write, FileShare.None, array_length))
{
using (BinaryWriter bwwrite = new BinaryWriter(fswrite))
{
for (; ; )
{
int read = bwread.Read(dataArray, 0, array_length);
if (0 == read)
break;
bwwrite.Write(dataArray, 0, read);
worker.ReportProgress((int)(fsread.Position * 100 / fsread.Length));

if (worker.CancellationPending)
{
// e.Cancel = true;
worker.ReportProgress(0);
fsread.Close();
fsread.Close();
return;
}

}
}
}
}
}
// File.Delete(source);


}

qasemf
پنج شنبه 23 بهمن 1399, 22:22 عصر
مهندس حل شد یه اشتباه فاحش انجام داده بودم ولی مشکل رو فهمیدم و حلش کردم بازم ممنون از کمکتون