|
No, you don't.
UI stuff like that should happen outside the BackgroundWorker, like right before you start it on its way.
|
|
|
|
|
1) Add reference to WindowsBase.dll
2) Add: using System.Windows.Threading;
3) Add delegate declaration OUTSIDE of method:
delegate void ProgressDelegate( int pct );
4) Replace (in this case):
backgroundWorker1.ReportProgress(i);
with:
ProgressDelegate progressDelegate = delegate ( int pct ) { this.progressBar1.Value = pct; };
System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
DispatcherPriority.Normal, progressDelegate, percentComplete );
Then it's just a matter of tailoring for various UI controls.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it.
― Confucian Analects: Rules of Confucius about his food
|
|
|
|
|
Isn't that the same question that you ask here :
Re: BackGroundWorker gives runtime error - C# Discussion Boards[^]
Did you give those links, I gave to you at that question, a try ?
If not - why not ?
If yes - where do you stuck ?
To Clarify :
Invoke means that you give an order to do something outside your Thread or Worker which originally happen inside the UI-Thread.
|
|
|
|
|
That basically is the same question once more. The answer hasn't changed.
You are wasting your and our time by repeating your question and ignoring the answers you've got.
Luc Pattyn [My Articles]
If you can't find it on YouTube try TikTok...
|
|
|
|
|
Luc Pattyn wrote: No, Master Luke.
(Ghhh.. I am your father, ghhhh)
Luc Pattyn wrote: You are wasting your and our time He has the right to do so; to be ignorant. There's always those looking for easy answers, unwilling to learn. This site is easy money for some. I learned a lot from you, mostly that I should be patient.
Want to tell him he's wasting money? This is voluntary, remember? If he insist on failing, I'd for one gladly help.
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
I'm not wasting your time. I couldn't find out how to use the procedure in my own situation.
For example, based on the explanations in Towards Cleaner Code II, a C# GUI Invoke/Async Helper [^] I wrote the following code:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
if (button1.InvokeRequired)
{
button1.Invoke(delegate { updatetext("Processing"); });
}
else
{
updatetext("Processing");
}
int sum = 0;
for (int i = 0; i <= 100; i++)
{
Thread.Sleep(100);
sum = sum + i;
backgroundWorker1.ReportProgress(i);
if (backgroundWorker1.CancellationPending)
{
e.Cancel = true;
backgroundWorker1.ReportProgress(0);
return;
}
}
e.Result = sum;
}
private void updatetext(string txt)
{
button1.Text = txt;
}
But,
button1.Invoke(delegate { updatetext("Processing"); }); says the method is not a delegate type and cannot be compiled.
modified 12-Feb-21 0:54am.
|
|
|
|
|
I found my own solution:
button1.Invoke((Action)delegate { updatetext("Processing"); });
or
button1.Invoke((MethodInvoker)delegate { updatetext("Processing"); });
|
|
|
|
|
Message Closed
modified 13-Feb-21 8:00am.
|
|
|
|
|
|
Good morning I have a problem that is making me desperate. I want to deserelize a Json but the content is always null. I pass you my code, if you could give me a hand I would appreciate it very much.
Regards and thank you very much in advance.
CLASS
public class RootContactos
{
public string contacto { get; set; }
public string email { get; set; }
public string telefono { get; set; }
public string notas { get; set; }
}
CODE
contac = JsonConvert.DeserializeObject<rootcontactos>(strJson);
JSON
{"20150630140000#1":{"contacto":"PATRICIA","telefono":"976185823","email":"","notas":""},"20150630140001#1":{"contacto":"FAX","telefono":"976180364","email":"","notas":""}}
|
|
|
|
|
Your JSON does not match the class, which is probably why you get a problem. If I run your JSON through a class creator (Convert JSON to C# Classes Online - Json2CSharp Toolkit[^]) then what I get is three classes:
public class _201506301400001 {
public string contacto { get; set; }
public string telefono { get; set; }
public string email { get; set; }
public string notas { get; set; }
}
public class _201506301400011 {
public string contacto { get; set; }
public string telefono { get; set; }
public string email { get; set; }
public string notas { get; set; }
}
public class Root {
[JsonProperty("20150630140000#1")]
public _201506301400001 _201506301400001 { get; set; }
[JsonProperty("20150630140001#1")]
public _201506301400011 _201506301400011 { get; set; }
} Which is what I would expect from that: two different classes with identical content but different names!
I'd start by looking at the data source - I'd expect an array of JSON data containing two elements, not two individual items.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thank you very much for answering. The classes that he proposes to me, I cannot perform them because the "header" (_201506301400001) varies in each record of the database.
I have been testing and I have managed to do the deserilization in this way:
var result = JsonConvert.DeserializeObject <dynamic> (strJson);
But then I have not gotten the information from resutl.
Regards and thank you very much in advance.
|
|
|
|
|
Deserialize it into a Dictionary.
void Main()
{
var json =@"{""20150630140000#1"":{""contacto"":""PATRICIA"",""telefono"":""976185823"",""email"":"""",""notas"":""""},""20150630140001#1"":{""contacto"":""FAX"",""telefono"":""976180364"",""email"":"""",""notas"":""""}}";
<pre>
var contacDict = JsonConvert.DeserializeObject<IDictionary<string,RootContactos>>(json);
contacDict.Values.First().Dump();
contacDict["20150630140001#1"].Dump();
}
public class RootContactos
{
public string contacto { get; set; }
public string email { get; set; }
public string telefono { get; set; }
public string notas { get; set; }
}</pre>
Truth,
James
|
|
|
|
|
Thank you very much it has worked perfectly.
Regards, and thank you very much.
|
|
|
|
|
I'm working on Devexpress Spreadsheet application. My calculation are as below:
1. Data is read from a sheet into two Lists. One list is string type and another is integer type. String type list consists of values of 4 cells in each row.
2. Lists are put into a dictionary. Strings are keys and integers are values.
3. Values of the same keys are summed.
4. The mentioned two lists are cleared and fill by dictionary keys and values.
5. Dictionary keys and values are split into cells in a new sheet.
I want to show progress animation (comes with DevExpress tools) when calculations begin. I used following code:
<pre lang="C#"> private void barButtonItem5_ItemClick(object sender, ItemClickEventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
IWorkbook workbook = spreadsheetControl.Document;
Worksheet worksheet = workbook.Worksheets.ActiveWorksheet;
CellRange range = worksheet.GetDataRange();
int LastRow = range.BottomRowIndex;
var keys = new List<string>();
var values = new List<int>();
progressPanel1.Visible = true;
for (int i = 0; i < LastRow + 1; i++)
{
if (worksheet.Cells[i, 10].DisplayText == "خاتمه یافته")
{
keys.Add(string.Join(",", worksheet.Cells[i, 28].DisplayText, worksheet.Cells[i, 0].DisplayText, worksheet.Cells[i, 9].DisplayText,
worksheet.Cells[i, 15].DisplayText, worksheet.Cells[i, 31].DisplayText));
values.Add((int)worksheet.Cells[i, 32].Value.NumericValue);
}
}
var mydic = new Dictionary<string, int>();
for (int i = 0; i < keys.Count; i++)
{
if (mydic.ContainsKey(keys[i]))
{
mydic[keys[i]] += values[i];
}
else
{
mydic.Add(keys[i], values[i]);
}
}
if (worksheet.HasData)
{
if (workbook.Worksheets.Contains("Summarized") == false)
{
workbook.Worksheets.Add().Name = "Summarized";
}
Worksheet ws_summarized = workbook.Worksheets["Summarized"];
ws_summarized.Clear(workbook.Worksheets["Summarized"].GetUsedRange());
keys.Clear();
values.Clear();
foreach (var item in mydic.Keys)
{
keys.Add(item);
}
foreach (var item in mydic.Values)
{
values.Add(item);
}
for (int i = 0; i < mydic.Count; i++)
{
string text = keys[i];
string[] rewrite = text.Split(',');
workbook.Worksheets["Summarized"].Cells[i, 0].SetValue(rewrite[0]);
workbook.Worksheets["Summarized"].Cells[i, 1].SetValue(rewrite[1]);
workbook.Worksheets["Summarized"].Cells[i, 2].SetValue(rewrite[2]);
workbook.Worksheets["Summarized"].Cells[i, 3].SetValue(rewrite[3]);
workbook.Worksheets["Summarized"].Cells[i, 4].SetValue(rewrite[4]);
}
for (int i = 0; i < mydic.Count; i++)
{
int text = values[i];
workbook.Worksheets["Summarized"].Cells[i, 5].SetValue(text);
}
}
else
{
MessageBox.Show("خطای داده ورودی", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
When I run and press the dedicated button, the following runtime error occurs:
System.InvalidOperationException: 'Cross-thread operation not valid: Control 'spreadsheetFormulaBarPanel' accessed from a thread other than the thread it was created on.'
The error in in line
progressPanel1.Visible = true;
I tried to delete that line and check whether it works. This time the following runtime error occurred:
System.InvalidOperationException: 'This BackgroundWorker is currently busy and cannot run multiple tasks concurrently.'
This error occurs in line
backgroundWorker1.RunWorkerAsync();
PLEASE HELP ME.
|
|
|
|
|
You cannot access UI controls from any other thread than the original UI thread: if you try, you will cause a Cross Threading Exception.
So when you do this:
progressPanel1.Visible = true; in the BackgroundWorker DoWork event, you will immediately error the thread.
The BackgroundWorker includes progress reporting, which is automatically routed back to the UI thread so it is entirely safe to access controls from the ProgressChanged event[^]. But not from anywhere else!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thanks. I wrote the code in ProgressChanged event.
What about the other runtime error? It still says:
"System.InvalidOperationException: 'This BackgroundWorker is currently busy and cannot run multiple tasks concurrently.'"
This error occurs in the line below:
backgroundWorker1.RunWorkerAsync();
|
|
|
|
|
A BackgroungWorker is a thread - if it's busy doing something, you can't start it again!
Normally, I create a BW, add the dowork and progress event handlers, then a BackgroundWorker.RunWorkerCompleted Event (System.ComponentModel) | Microsoft Docs[^] event which tells the main thread it's all done. If in the meantime I need another, I create one and go through the same process with that.
Don't recycle them: create one when you need it, use it and dispose it!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
How many BW do I need in my example?
Do I need to add them from designing window?
|
|
|
|
|
No idea ... but I don't use the designer except for UI controls - BW isn't that, and I create them in code as needed. It's trivial to do.
Here's my code for the UI component of my file mover:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.IO;
using System.Data.SqlClient;
using BackgroundFileMove.UtilityCode;
using System.Windows.Forms;
using Microsoft.WindowsAPICodePack.Taskbar;
using System.Reflection;
namespace BackgroundFileMove
{
public partial class frmMoveFilesInBackground : Form
{
#region Constants
private const int blockSize = 8 * 1024 * 1024;
#endregion
#region Fields
#region Internal
private volatile bool cancel = false;
private FileMove.MoveFile moveDelegate;
private FileMove.UpdateDB updateDelegate;
private IEnumerable<FileMove> files;
private string moveFileAction;
private string updateDBAction;
private string skippingAction;
private bool closeOnDone;
private byte[] transfer = new byte[blockSize];
private bool doCopyOnly = false;
#endregion
#region Property bases
#endregion
#endregion
#region Properties
public bool IsProcessing { get { return butStop.Enabled; } }
#endregion
#region Regular Expressions
#endregion
#region Enums
#endregion
#region Classes
private class ProgressReport
{
public string Filename { get; set; }
public string Action { get; set; }
public int FileNumber { get; set; }
public int FilesCount { get; set; }
public int FilePercentage { get; set; }
}
#endregion
#region Constructors
public frmMoveFilesInBackground(IEnumerable<FileMove> files,
FileMove.MoveFile moveDelegate = null,
FileMove.UpdateDB updateDelegate = null,
string moveFileAction = null,
string updateDBAction = null,
string skippingAction = null,
bool closeOnDone = false)
{
InitializeComponent();
if (moveFileAction == null) moveFileAction = "Moving title...";
if (updateDBAction == null) updateDBAction = "Updating database...";
if (skippingAction == null) skippingAction = "Skipping title...";
this.moveDelegate = moveDelegate;
this.updateDelegate = updateDelegate;
this.files = files;
this.moveFileAction = moveFileAction;
this.updateDBAction = updateDBAction;
this.skippingAction = skippingAction;
this.closeOnDone = closeOnDone;
string initData = "";
tbInfo.Text = initData;
tbInfo.Visible = cancel;
}
#endregion
#region Events
#region Event Constructors
public event EventHandler MoveCompleted;
protected virtual void OnMoveCompleted(EventArgs e)
{
EventHandler eh = MoveCompleted;
if (eh != null)
{
eh(this, e);
}
}
#endregion
#region Event Handlers
#region Form
private void frmMoveFilesInBackground_Shown(object sender, EventArgs e)
{
DoBackgroundMove();
}
private void frmMoveFilesInBackground_Load(object sender, EventArgs e)
{
if ((ModifierKeys & Keys.Shift) == 0)
{
this.LoadLocation();
}
}
private void frmMoveFilesInBackground_FormClosing(object sender, FormClosingEventArgs e)
{
if ((ModifierKeys & Keys.Shift) == 0)
{
this.SaveLocation();
}
}
#endregion
#region Buttons
private void butStop_Click(object sender, EventArgs e)
{
cancel = true;
}
#endregion
#region Worker
private void tidyFiles_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (worker != null)
{
int fileNumber = 1;
worker.ReportProgress(0, new ProgressReport { Action = "Initializing", Filename = "", FileNumber = 0, FilesCount = 0 });
foreach (FileMove file in files)
{
ProgressReport pr = new ProgressReport { FilesCount = files.Count() };
if (cancel)
{
pr.Action = "Cancelled by user";
pr.Filename = "";
worker.ReportProgress(pr.FilesCount, pr);
break;
}
string title = file.Title;
string fnOld = file.OldPath;
string fnNew = file.NewPath;
Guid id = file.FileID;
pr.FileNumber = fileNumber;
pr.Filename = Path.GetFileNameWithoutExtension(fnOld);
if (fnNew != fnOld)
{
try
{
pr.Action = moveFileAction;
worker.ReportProgress(fileNumber, pr);
if (moveDelegate != null)
{
if (!moveDelegate(file))
{
continue;
}
}
else
{
if (File.Exists(fnOld))
{
string path = Path.GetDirectoryName(fnNew);
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
MoveFile(fnOld, fnNew, worker, pr);
}
else if (!File.Exists(fnNew))
{
throw new IOException("Neither the source nor the destination files could be found");
}
}
if (updateDelegate != null)
{
pr.Action = updateDBAction;
worker.ReportProgress(fileNumber, pr);
if (!updateDelegate(file))
{
break;
}
}
}
catch (Exception ex)
{
string problem = string.Format("Problem with:\n \"{0}\"\n \"{1}\"\n \"{2}\"\n {3}\n", title, fnOld, fnNew, ex);
worker.ReportProgress(fileNumber, new ProgressReport
{
Action = problem,
Filename = fnOld,
FileNumber = fileNumber,
FilesCount = files.Count()
});
}
}
else
{
pr.Action = skippingAction;
worker.ReportProgress(fileNumber, pr);
}
fileNumber++;
}
}
}
private void tidyFiles_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
int progress = e.ProgressPercentage;
ProgressReport report = e.UserState as ProgressReport;
if (report == null)
{
tbInfo.Text = "Working...";
pbShow.Visible = false;
}
else
{
tbInfo.Lines = string.Format("{0}\n{1}/{2}\n{3}", report.Action, report.FileNumber, report.FilesCount, report.Filename).Split('\n');
pbShow.Maximum = report.FilesCount;
pbShow.Visible = true;
if (progress >= 0)
{
int newIndex = dgvHistory.Rows.Add(report.Action, report.Filename);
dgvHistory.CurrentCell = dgvHistory.Rows[newIndex].Cells[0];
Text = string.Format("Moving: {0}", report.Action);
TaskbarManager.Instance.SetProgressValue(report.FileNumber, report.FilesCount);
}
else
{
progress = -progress;
}
}
tbInfo.Visible = true;
if (report.FilePercentage > 0)
{
pbFileProgress.Visible = true;
pbFileProgress.Value = report.FilePercentage;
}
else
{
pbFileProgress.Visible = false;
}
pbShow.Value = progress;
}
private void tidyFiles_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pbShow.Visible = false;
pbFileProgress.Visible = false;
butStop.Enabled = false;
tbInfo.Text = "Completed";
Text = "Move operation completed";
TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.NoProgress);
OnMoveCompleted(new EventArgs());
if (closeOnDone)
{
Close();
}
}
#endregion
#endregion
#endregion
#region Public Methods
public void Cancel()
{
if (IsProcessing)
{
cancel = true;
}
}
public void SteathMove()
{
DoBackgroundMove();
}
#endregion
#region Public Static Methods
#region Do Copy
public static frmMoveFilesInBackground DoCopy(string sourceFolder,
string destinationFolder,
IEnumerable<string> wantedExtensions = null,
IEnumerable<string> unwantedExtensions = null,
FileMove.MoveFile moveDelegate = null,
FileMove.UpdateDB updateDelegate = null,
string moveFileAction = null,
string updateDBAction = null,
string skippingAction = null,
bool closeOnDone = false)
{
if (unwantedExtensions == null) unwantedExtensions = new List<string>();
List<FileMove> files = new List<FileMove>();
Cursor.Current = Cursors.WaitCursor;
string[] rawData = Directory.GetFiles(sourceFolder, "*.*", SearchOption.AllDirectories);
files.AddRange(rawData.Where(r => (wantedExtensions == null ? true : wantedExtensions.Contains(Path.GetExtension(r))) &&
!unwantedExtensions.Contains(Path.GetExtension(r)))
.Select(w => new FileMove(Path.GetFileNameWithoutExtension(w), w, w.Replace(sourceFolder, destinationFolder))));
Cursor.Current = Cursors.Default;
return DoCopy(files, moveDelegate, updateDelegate, moveFileAction, updateDBAction, skippingAction, closeOnDone);
}
public static frmMoveFilesInBackground DoCopy(IEnumerable<FileMove> files,
FileMove.MoveFile moveDelegate = null,
FileMove.UpdateDB updateDelegate = null,
string moveFileAction = null,
string updateDBAction = null,
string skippingAction = null,
bool closeOnDone = false)
{
frmMoveFilesInBackground move = new frmMoveFilesInBackground(files, moveDelegate, updateDelegate, moveFileAction, updateDBAction, skippingAction, closeOnDone);
move.doCopyOnly = true;
move.Show();
Cursor.Current = Cursors.Default;
return move;
}
#endregion
#region Do Move
public static frmMoveFilesInBackground DoMove(string sourceFolder,
string destinationFolder,
IEnumerable<string> wantedExtensions = null,
IEnumerable<string> unwantedExtensions = null,
FileMove.MoveFile moveDelegate = null,
FileMove.UpdateDB updateDelegate = null,
string moveFileAction = null,
string updateDBAction = null,
string skippingAction = null,
bool closeOnDone = false)
{
if (unwantedExtensions == null) unwantedExtensions = new List<string>();
List<FileMove> files = new List<FileMove>();
Cursor.Current = Cursors.WaitCursor;
string[] rawData = Directory.GetFiles(sourceFolder, "*.*", SearchOption.AllDirectories);
files.AddRange(rawData.Where(r => (wantedExtensions == null ? true : wantedExtensions.Contains(Path.GetExtension(r))) &&
!unwantedExtensions.Contains(Path.GetExtension(r)))
.Select(w => new FileMove(Path.GetFileNameWithoutExtension(w), w, w.Replace(sourceFolder, destinationFolder))));
Cursor.Current = Cursors.Default;
return DoMove(files, moveDelegate, updateDelegate, moveFileAction, updateDBAction, skippingAction, closeOnDone);
}
public static frmMoveFilesInBackground DoMove(IEnumerable<FileMove> files,
FileMove.MoveFile moveDelegate = null,
FileMove.UpdateDB updateDelegate = null,
string moveFileAction = null,
string updateDBAction = null,
string skippingAction = null,
bool closeOnDone = false)
{
frmMoveFilesInBackground move = new frmMoveFilesInBackground(files, moveDelegate, updateDelegate, moveFileAction, updateDBAction, skippingAction, closeOnDone);
move.Show();
Cursor.Current = Cursors.Default;
return move;
}
#endregion
public static string GetRevisionHistory()
{
Assembly assembly = Assembly.GetExecutingAssembly();
Stream stream = assembly.GetManifestResourceStream("BackgroundFileMove.Resources.Documents.RevisionHistory.txt");
StreamReader reader = new StreamReader(stream);
return reader.ReadToEnd();
}
public static bool IsDriveAvailable(string path)
{
DriveInfo[] drives = DriveInfo.GetDrives();
DriveInfo drive = drives.FirstOrDefault(d => path.StartsWith(d.Name));
return drive != null && drive.IsReady;
}
#endregion
#region Overrides
#endregion
#region Private Methods
private void DoBackgroundMove()
{
if (!cancel)
{
TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal);
BackgroundWorker tidyFiles = new BackgroundWorker();
tidyFiles.WorkerReportsProgress = true;
tidyFiles.DoWork += new DoWorkEventHandler(tidyFiles_DoWork);
tidyFiles.ProgressChanged += new ProgressChangedEventHandler(tidyFiles_ProgressChanged);
tidyFiles.RunWorkerCompleted += new RunWorkerCompletedEventHandler(tidyFiles_RunWorkerCompleted);
tidyFiles.RunWorkerAsync();
butStop.Enabled = true;
}
}
private void MoveFile(string src, string dst, BackgroundWorker worker = null, ProgressReport prMain = null)
{
if (src != dst)
{
int iSrc = src.IndexOf(':');
int iDst = dst.IndexOf(':');
FileInfo fiSrc = new FileInfo(src);
if (fiSrc.Length < blockSize || (iSrc > 0 && iDst > 0 && iSrc == iDst && src.Substring(0, iSrc) == dst.Substring(0, iDst)))
{
if (doCopyOnly)
{
File.Copy(src, dst);
}
else
{
File.Move(src, dst);
}
}
else
{
using (Stream sr = new FileStream(src, FileMode.Open))
{
using (Stream sw = new FileStream(dst, FileMode.Create))
{
long total = sr.Length;
long bytes = 0;
long cnt = total;
int progress = 0;
while (cnt > 0)
{
int n = sr.Read(transfer, 0, blockSize);
sw.Write(transfer, 0, n);
bytes += n;
cnt -= n;
int percent = (int)((bytes * 100) / total);
if (progress != percent)
{
progress = percent;
if (worker != null && prMain != null)
{
ProgressReport pr = new ProgressReport
{
FilesCount = prMain.FilesCount,
FileNumber = prMain.FileNumber,
Filename = prMain.Filename,
Action = prMain.Action,
FilePercentage = percent
};
worker.ReportProgress(-prMain.FileNumber, pr);
}
}
}
}
}
FileInfo fiDst = new FileInfo(dst);
fiDst.Attributes = fiSrc.Attributes;
fiDst.CreationTime = fiSrc.CreationTime;
fiDst.CreationTimeUtc = fiSrc.CreationTimeUtc;
fiDst.IsReadOnly = fiSrc.IsReadOnly;
fiDst.LastAccessTime = fiSrc.LastAccessTime;
fiDst.LastAccessTimeUtc = fiSrc.LastAccessTimeUtc;
fiDst.LastWriteTime = fiSrc.LastWriteTime;
fiDst.LastWriteTimeUtc = fiSrc.LastWriteTimeUtc;
if (!doCopyOnly)
{
File.Delete(src);
}
}
}
}
#endregion
}
} Look at the DoBackgroundMove method - it builds the worker as needed and kicks it off to throw files around (normally between my HDD and NAS, which is a relatively slow operation)
To use it, I construct the form instance, pass it the files list and show it - it then updates my as it moves the files.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I finally could use Invoke to avoid cross-threading. But, UI still freezes and non-responsive during UI calculations.
My final code:
private void barButtonItem5_ItemClick(object sender, ItemClickEventArgs e)
{
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync();
}
}
private void CreateSheet(string _sheetName)
{
IWorkbook workbook = spreadsheetControl.Document;
if (workbook.Worksheets.Contains(_sheetName) == false)
{
workbook.Worksheets.Add().Name = _sheetName;
}
}
private void ClearSheet(string _sheetName)
{
IWorkbook workbook = spreadsheetControl.Document;
var keys = new List<string>();
var values = new List<int>();
Worksheet ws_summarized = workbook.Worksheets[_sheetName];
ws_summarized.Clear(workbook.Worksheets[_sheetName].GetUsedRange());
keys.Clear();
values.Clear();
}
private void FillCell(string _sheetName)
{
IWorkbook workbook = spreadsheetControl.Document;
Worksheet worksheet = workbook.Worksheets["DataSet1"];
CellRange range = worksheet.GetDataRange();
int LastRow = range.BottomRowIndex;
var keys = new List<string>();
var values = new List<int>();
for (int i = 0; i < LastRow + 1; i++)
{
if (worksheet.Cells[i, 10].DisplayText == "خاتمه یافته")
{
keys.Add(string.Join(",", worksheet.Cells[i, 28].DisplayText, worksheet.Cells[i, 0].DisplayText, worksheet.Cells[i, 9].DisplayText,
worksheet.Cells[i, 15].DisplayText, worksheet.Cells[i, 31].DisplayText));
values.Add((int)worksheet.Cells[i, 32].Value.NumericValue);
}
}
var mydic = new Dictionary<string, int>();
for (int i = 0; i < keys.Count; i++)
{
if (mydic.ContainsKey(keys[i]))
{
mydic[keys[i]] += values[i];
}
else
{
mydic.Add(keys[i], values[i]);
}
}
foreach (var item in mydic.Keys)
{
keys.Add(item);
}
foreach (var item in mydic.Values)
{
values.Add(item);
}
for (int i = 0; i < mydic.Count; i++)
{
string text = keys[i];
string[] rewrite = text.Split(',');
workbook.Worksheets[_sheetName].Cells[i, 0].SetValue(rewrite[0]);
workbook.Worksheets[_sheetName].Cells[i, 1].SetValue(rewrite[1]);
workbook.Worksheets[_sheetName].Cells[i, 2].SetValue(rewrite[2]);
workbook.Worksheets[_sheetName].Cells[i, 3].SetValue(rewrite[3]);
workbook.Worksheets[_sheetName].Cells[i, 4].SetValue(rewrite[4]);
}
for (int i = 0; i < mydic.Count; i++)
{
int text = values[i];
workbook.Worksheets[_sheetName].Cells[i, 5].SetValue(text);
}
}
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
IWorkbook workbook = spreadsheetControl.Document;
Worksheet worksheet = workbook.Worksheets["DataSet1"];
if (worksheet.HasData)
{
if (spreadsheetBarController1.Control.InvokeRequired)
{
spreadsheetBarController1.Control.Invoke((Action)delegate { CreateSheet("Summarized"); });
spreadsheetBarController1.Control.Invoke((MethodInvoker)delegate { ClearSheet("Summarized"); });
spreadsheetBarController1.Control.Invoke((Action)delegate { FillCell("Summarized"); });
}
}
else
{
MessageBox.Show("خطای داده ورودی", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
progressPanel1.Visible = false;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressPanel1.Visible = true;
}
}
|
|
|
|
|
Yes it will.
Because you have moved all of the code that processes stuff back to the UI thread by invoking it.
That's what Invoke does - it moves execution to the UI thread so that controls can be accessed.
What you are supposed to do is do the work on the BackgroundWorker, and pass the result for display to the UI thread via a progress report, not start a second thread and then invoke it all back onto the main thread. Do you not understand threading at all?
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
modified 12-Feb-21 8:45am.
|
|
|
|
|
I made some changes in my code. I used datatable for filling spreadsheet. I tried to pass UI related works (filling cells) to ProgressChanged event.
But it still freezes when filling spreadsheet.
private void barButtonItem5_ItemClick(object sender, ItemClickEventArgs e)
{
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync();
}
}
private void CreateSheet(string _sheetName)
{
IWorkbook workbook = spreadsheetControl.Document;
if (workbook.Worksheets.Contains(_sheetName) == false)
{
workbook.Worksheets.Add().Name = _sheetName;
}
}
private void ClearSheet(string _sheetName)
{
IWorkbook workbook = spreadsheetControl.Document;
var keys = new List<string>();
var values = new List<int>();
Worksheet ws_summarized = workbook.Worksheets[_sheetName];
ws_summarized.Clear(workbook.Worksheets[_sheetName].GetUsedRange());
keys.Clear();
values.Clear();
}
DataTable my_table = new DataTable();
DataTable my_table2 = new DataTable();
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
IWorkbook workbook = spreadsheetControl.Document;
Worksheet worksheet = workbook.Worksheets["DataSet1"];
CellRange range = worksheet.GetDataRange();
int LastRow = range.BottomRowIndex;
var keys = new List<string>();
var values = new List<int>();
for (int i = 0; i < LastRow + 1; i++)
{
if (worksheet.Cells[i, 10].DisplayText == "خاتمه یافته")
{
keys.Add(string.Join(",", worksheet.Cells[i, 28].DisplayText, worksheet.Cells[i, 0].DisplayText, worksheet.Cells[i, 9].DisplayText,
worksheet.Cells[i, 15].DisplayText, worksheet.Cells[i, 31].DisplayText));
values.Add((int)worksheet.Cells[i, 32].Value.NumericValue);
}
}
if (worksheet.HasData)
{
if (spreadsheetBarController1.Control.InvokeRequired)
{
spreadsheetBarController1.Control.Invoke((Action)delegate { CreateSheet("Summarized"); });
spreadsheetBarController1.Control.Invoke((MethodInvoker)delegate { ClearSheet("Summarized"); });
}
var mydic = new Dictionary<string, int>();
for (int i = 0; i < keys.Count; i++)
{
if (mydic.ContainsKey(keys[i]))
{
mydic[keys[i]] += values[i];
}
else
{
mydic.Add(keys[i], values[i]);
}
}
keys.Clear();
values.Clear();
foreach (var item in mydic.Keys)
{
keys.Add(item);
}
foreach (var item in mydic.Values)
{
values.Add(item);
}
my_table.Columns.Add("A");
my_table.Columns.Add("B");
my_table.Columns.Add("C");
my_table.Columns.Add("D");
my_table.Columns.Add("E");
for (int i = 0; i < mydic.Count; i++)
{
string text = keys[i];
string[] rewrite = text.Split(',');
my_table.Rows.Add(rewrite[0], rewrite[1], rewrite[2], rewrite[3], rewrite[4]);
}
my_table2.Columns.Add("F");
for (int i = 0; i < mydic.Count; i++)
{
int text = values[i];
my_table2.Rows.Add(text);
}
backgroundWorker1.ReportProgress(100);
}
else
{
MessageBox.Show("خطای داده ورودی", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
progressPanel1.Visible = false;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
IWorkbook workbook = spreadsheetControl.Document;
Worksheet worksheet = workbook.Worksheets["DataSet1"];
CellRange range = worksheet.GetDataRange();
int LastRow = range.BottomRowIndex;
for (int i = 0; i < my_table.Rows.Count; i++)
{
workbook.Worksheets["Summarized"].Cells[i, 0].SetValue(my_table.Rows[i]["A"].ToString());
workbook.Worksheets["Summarized"].Cells[i, 1].SetValue(my_table.Rows[i]["B"].ToString());
workbook.Worksheets["Summarized"].Cells[i, 2].SetValue(my_table.Rows[i]["C"].ToString());
workbook.Worksheets["Summarized"].Cells[i, 3].SetValue(my_table.Rows[i]["D"].ToString());
workbook.Worksheets["Summarized"].Cells[i, 4].SetValue(my_table.Rows[i]["E"].ToString());
}
}
|
|
|
|
|
If you want to work with the UI-Control (as Griff mentioned) you have to use Invoke - there are a lot of samples for this inside the Internet.
Your other problem could be solved if you first look if the Backgroundworker is allready busy before you start it ...
|
|
|
|
|
I make change the following code:
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync();
}
Now, The following runtime error occurs:
"System.InvalidOperationException: 'Cross-thread operation not valid: Control '' accessed from a thread other than the thread it "
The error is in line
workbook.Worksheets.Add().Name = "Summarized";
How to fix this?
|
|
|
|
|