Below code is used to move the data from local system to external hard drives. Client's requirement is to use threading for the same so as to speed up the copy of pages / minute.
I am facing one issue. I used continue statement under while loop which is not acceptable under thread. Can someone please suggest alternative of the same.
Thanks.
private void PromoteMain(TextWriter streamWriter)
{
string driveLetterString;
driveLetterString = GetExternalDrive();
if (!string.IsNullOrEmpty(driveLetterString))
{
DataSet dataSet;
DateTime startSnooze;
DataRow row;
string imageIdString;
string reelIdString;
string destImagePathString;
string[] strArrays;
int i;
string fileName;
string[] strArrays3;
string[] strArrays4;
bool flag;
string[] strArrays5;
bool flag1;
string[] strArrays6;
bool flag2;
string[] files;
TimeSpan timeSpan1;
IEnumerator iEnumerator1;
string[] stringArray1;
IDisposable iDisposable1;
dataSet = this.GetImagesFromDatabase();
if (((dataSet != null) && (dataSet.Tables.Count != 0)) && (dataSet.Tables[0].Rows.Count != 0))
{
iEnumerator1 = dataSet.Tables[0].Rows.GetEnumerator();
try
{
#region goto L_05A9
//goto L_05A9;
while (iEnumerator1.MoveNext())
{
driveLetterString = GetExternalDrive();
new Thread(() =>
{
if (!string.IsNullOrEmpty(driveLetterString))
{
row = ((DataRow)iEnumerator1.Current);
imageIdString = row["imageid"].ToString();
reelIdString = row["reelid"].ToString();
destImagePathString = row["destimagepath"].ToString();
if (!Directory.Exists(destImagePathString))
{
if (this.stringBuilderFail.Length > 0)
{
StringBuilder stringBuilder7 = this.stringBuilderFail.Append(",");
}
StringBuilder stringBuilder8 = this.stringBuilderFail.Append(imageIdString);
this._lblFailed.Text = Convert.ToString(((int)(Convert.ToInt32(this._lblFailed.Text) + 1)));
if (this.stringBuilderFail.Length > 7000)
{
this.UpdateImagesInDatabase(this.stringBuilderFail.ToString(), "5");
StringBuilder stringBuilder9 = this.stringBuilderFail.Remove(0, this.stringBuilderFail.Length);
}
this.RefreshFormView();
continue;
}
if (!Directory.Exists((driveLetterString + "newspaper\\" + reelIdString + "\\")))
{
DirectoryInfo directoryInfo1 = Directory.CreateDirectory((driveLetterString + "newspaper\\" + reelIdString + "\\"));
}
strArrays = new string[] { ".pdf", ".html", "_clean.html", "_lx.jpg" };
for (i = 0; (i < strArrays.Length); i++)
{
fileName = strArrays[i];
try
{
if (i != 2)
{
strArrays3 = new string[] { driveLetterString, "newspaper\\", reelIdString, "\\", imageIdString, fileName };
File.Copy((destImagePathString + imageIdString + fileName), string.Concat(strArrays3));
}
}
catch
{
}
}
strArrays4 = new string[] { driveLetterString, "newspaper\\", reelIdString, "\\", imageIdString, ".pdf" };
flag = File.Exists(string.Concat(strArrays4));
strArrays5 = new string[] { driveLetterString, "newspaper\\", reelIdString, "\\", imageIdString, "_lx.jpg" };
flag1 = File.Exists(string.Concat(strArrays5));
strArrays6 = new string[] { driveLetterString, "newspaper\\", reelIdString, "\\", imageIdString, ".html" };
flag2 = File.Exists(string.Concat(strArrays6));
if ((flag && flag1) && flag2)
{
streamWriter.WriteLine(imageIdString);
if (this.stringBuilderSuccess.Length > 0)
{
StringBuilder stringBuilder3 = this.stringBuilderSuccess.Append(",");
}
StringBuilder stringBuilder4 = this.stringBuilderSuccess.Append(imageIdString);
this._lblPromoted.Text = Convert.ToString(((int)(Convert.ToInt32(this._lblPromoted.Text) + 1)));
#region goto L_0453
L_0453();
continue;
#endregion
}
files = Directory.GetFiles((driveLetterString + "newspaper\\" + reelIdString + "\\"), (imageIdString + "*.*"));
stringArray1 = files;
foreach (string str6 in stringArray1)
{
try
{
File.Delete(str6);
}
catch
{
}
}
if (this.stringBuilderFail.Length > 0)
{
StringBuilder stringBuilder1 = this.stringBuilderFail.Append(",");
}
StringBuilder stringBuilder2 = this.stringBuilderFail.Append(imageIdString);
this._lblFailed.Text = Convert.ToString(((int)(Convert.ToInt32(this._lblFailed.Text) + 1)));
#region goto L_0453
L_0453();
continue;
#endregion
}
else
{
break;
};
}).Start();
}
#endregion
}
finally
{
iDisposable1 = (iEnumerator1 as IDisposable);
if (iDisposable1 != null)
{
iDisposable1.Dispose();
}
}
if (this.stringBuilderSuccess.Length > 0)
{
this.UpdateImagesInDatabase(this.stringBuilderSuccess.ToString(), "3");
StringBuilder stringBuilder10 = this.stringBuilderSuccess.Remove(0, this.stringBuilderSuccess.Length);
}
if (this.stringBuilderFail.Length > 0)
{
this.UpdateImagesInDatabase(this.stringBuilderFail.ToString(), "5");
StringBuilder stringBuilder11 = this.stringBuilderFail.Remove(0, this.stringBuilderFail.Length);
}
this.RefreshFormView();
#region goto L_0671
PromoteMain(streamWriter);
#endregion
}
else
{
startSnooze = DateTime.Now;
timeSpan1 = DateTime.Now.Subtract(startSnooze);
while (timeSpan1.TotalSeconds < 300D)
{
timeSpan1 = DateTime.Now.Subtract(startSnooze);
Thread.Sleep(125);
Application.DoEvents();
}
PromoteMain(streamWriter);
}
}
//else
//{
// MessageBox.Show("There is no space in selected drives");
// //there is no space in any external drive
//}
}
private void L_0453()
{
if (this.stringBuilderSuccess.Length > 7000)
{
this.UpdateImagesInDatabase(this.stringBuilderSuccess.ToString(), "3");
StringBuilder stringBuilder5 = this.stringBuilderSuccess.Remove(0, this.stringBuilderSuccess.Length);
}
if (this.stringBuilderFail.Length > 7000)
{
this.UpdateImagesInDatabase(this.stringBuilderFail.ToString(), "5");
StringBuilder stringBuilder6 = this.stringBuilderFail.Remove(0, this.stringBuilderFail.Length);
}
this.RefreshFormView();
}
Replace the continue statement with a return. This will complete the execution of the thread. Now I don't know how this continue statement ended up there but you can't actually continue since the operations are running in parallel. You should also extract this line
row = ((DataRow)iEnumerator1.Current);
or you risk the enumerator to change from another thread before it executes. You may also want to try Parallel.Foreach to reduce possible errors and get more effective execution. Even better would be to use async methods with async IO (as opposed to methods that use threads) and use Task.WaitAll to wait for them to complete.
Related
Unresponsive UI using background worker, processing files are very slow.
Two different issues encountered here. GDpicture SDK is used for image processing. CPU Utilization is bare minimum, how can I maximize performance, ultimately have responsive and fast wpf application.
namespace OCR
{
public partial class MainWindow : Window
{
BackgroundWorker bw;/*= new BackgroundWorker();*/
private SynchronizationContext threadSyn = null;
string log_cap = string.Empty;
List<string> log_list = new List<string>();
string value = "Merged";
public MainWindow()
{
try
{
InitializeComponent();
InitializeBackgroundWorker();
File_process();
string configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"path.txt");
string[] configfile = File.ReadAllLines(configpath);
if (configfile.Length > 1)
{
ip.Text = configfile[0];
op.Text = configfile[1];
ex_tb.Text = configfile[2];
Protb.Text = configfile[3];
}
cbPDFConform.Items.Clear();
for (int i = 0; i < Enum.GetNames(typeof(PdfConformance)).Length - 1; i++)
{
ComboBoxItem cbi = new ComboBoxItem();
cbi.Content = Enum.GetName(typeof(PdfConformance), (PdfConformance)i);
PdfConformance test = (PdfConformance)i;
cbi.Tag = (PdfConformance)i;
cbPDFConform.Items.Add(cbi);
}
cbPDFConform.SelectedIndex = 0;
cbProcessorCount.Items.Clear();
for (int i = 1; i <= Environment.ProcessorCount; i++)
{
cbProcessorCount.Items.Add(i.ToString());
if (Environment.ProcessorCount / 2 == i) { cbProcessorCount.SelectedIndex = i - 1; }
}
LicenseManager oLicenseManager = new LicenseManager();
oLicenseManager.RegisterKEY("");
configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"path.txt");
configfile = File.ReadAllLines(configpath);
if (configfile.Length > 1)
{
ip.Text = configfile[0];
op.Text = configfile[1];
ex_tb.Text = configfile[2];
Protb.Text = configfile[3];
}
GrantAccess(ip.Text);
GrantAccess(op.Text);
GrantAccess(ex_tb.Text);
GrantAccess(Protb.Text);
threadSyn = SynchronizationContext.Current;
}
catch (Exception e1)
{ MessageBox.Show("e1" + e1.Message); }
}
private void InitializeBackgroundWorker()
{
bw = new BackgroundWorker();
bw.DoWork += Bw_DoWork;
bw.WorkerSupportsCancellation = true;
}
public async void File_process()
{
await Task.Run(() => converttiffpdfreducer());
}
private void Bw_DoWork(object sender, DoWorkEventArgs e)
{
this.Dispatcher.Invoke(() =>
{
try
{
using (StreamWriter sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"path.txt"), false))
{
sw.WriteLine(ip.Text);
sw.WriteLine(op.Text);
sw.WriteLine(ex_tb.Text);
sw.WriteLine(Protb.Text);
sw.Close();
}
ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = int.Parse(cbProcessorCount.SelectedItem.ToString());
var watch1 = new System.Diagnostics.Stopwatch();
watch1.Start();
converttiffpdfreducer();
//deletenew();
watch1.Stop();
TimeSpan ts1 = watch1.Elapsed;
ts1.ToString("mm\\:ss");
if (MergeChk.IsChecked == false)
{
value = "OCRed";
}
WriteLn("All documents have been successfully " + value + " " + ts1 + " " + DateTime.Now +" "+Environment.UserName);
}
catch (Exception DOwork)
{ MessageBox.Show("e2 " + DOwork.Message); }
});
}
private void GrantAccess(string fullPath)
{
DirectoryInfo dInfo = new DirectoryInfo(fullPath);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
dInfo.SetAccessControl(dSecurity);
}
private string[] mutliocr(string[] arr)
{
string box = string.Empty;
string box1 = string.Empty;
try
{
string filepath = string.Empty;
string outpath = ex_tb.Text;
if (MergeChk.IsChecked == true)
{ filepath = op.Text; }
else if (MergeChk.IsChecked == false)
{ filepath = Protb.Text; }
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
Thread.CurrentThread.IsBackground = true;
var watch2 = new System.Diagnostics.Stopwatch();
watch2.Start();
string[] getfilearray = arr;
for (int f = 0; f < getfilearray.Length; f++)
{
string dirName = Directory.GetParent(getfilearray[f]).FullName;
string folder = Directory.GetParent(getfilearray[f]).FullName;
box = Path.GetDirectoryName(getfilearray[f]);
box1 = Path.GetDirectoryName(box);
string getextension = Path.GetExtension(getfilearray[f]);
string[] newF = Directory.EnumerateFiles(dirName, "*.*", SearchOption.AllDirectories).ToArray();
string FN = Directory.GetParent(getfilearray[f]).Name;
string ocrfolder = (new FileInfo(getfilearray[f]).Directory.FullName);
string filen = Path.Combine(ocrfolder, folder, FN + "-ocr" + getextension);
string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
if (!Directory.Exists(ocrfolder))
{
Directory.CreateDirectory(ocrfolder);
}
GrantAccess(ocrfolder);
GdPicturePDF oGdPicturePDF = new GdPicturePDF();
oGdPicturePDF.OcrPagesDone += OcrPagesDone;
void OcrPagesDone(GdPictureStatus status1)
{
if (oGdPicturePDF.SaveToFile(filen) == GdPictureStatus.OK)
{ }
else
MessageBox.Show("PDF: The OCR-ed file has failed to save. Status: " + oGdPicturePDF.GetStat().ToString());
}
GdPictureStatus status = GdPictureStatus.OK;
if (oGdPicturePDF.LoadFromFile(getfilearray[f], false) == GdPictureStatus.OK)
if (status == GdPictureStatus.OK)
{
if (oGdPicturePDF.OcrPages_4("*", 0, "eng", dict, "", 300, OCRMode.FavorSpeed, 1, true) == GdPictureStatus.OK)
if (status == GdPictureStatus.OK)
{ }
else
{ MessageBox.Show("PDF: The OCR process has failed. Status: " + status.ToString()); }
}
else
{ MessageBox.Show("PDF: The PDF file has failed to load. Status: " + status.ToString()); }
oGdPicturePDF.Dispose();
GrantAccess(getfilearray[f]);
File.Delete(getfilearray[f]);
watch2.Stop();
TimeSpan ts2 = watch2.Elapsed;
ts2.ToString("mm\\:ss");
WriteLn(" OCR pages " + filen.Replace(op.Text, "") + " " + ts2 + " " + DateTime.Now);
}
if (MergeChk.IsChecked == true)
{
foreach (string str in Directory.EnumerateFiles(op.Text, "*.pdf", SearchOption.AllDirectories).ToArray())
{
if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4) + ".pdf"));
}
}
if (MergeChk.IsChecked == false)
{
FileSystem.MoveDirectory(Protb.Text, op.Text, UIOption.AllDialogs);
Directory.CreateDirectory(Protb.Text);
string FF = string.Empty;
foreach (string str in Directory.EnumerateFiles(op.Text, "*.pdf", SearchOption.AllDirectories))
{
if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4) + ".pdf"));
}
}
}));
}
catch (Exception mul)
{
}
return arr;
}
public static string browseFolder()
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = fbd.ShowDialog();
string path = string.Empty;
if (result == (System.Windows.Forms.DialogResult)MessageBoxResult.OK)
{
path = fbd.SelectedPath;
if (path[path.Length - 1] != '\\')
{
path = path + "\\";
}
}
return path;
}
private string[] converttiffpdfreducer()
{
string[] dir = null;
string box = string.Empty;
string box1 = string.Empty;
string[] gg = null;
try
{
string filepath = ip.Text;
string outpath = Protb.Text;
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
PdfConformance optPDFConform = PdfConformance.Unknown;
dir = Directory.EnumerateDirectories(filepath, "*.*", SearchOption.AllDirectories).Where(l => l.Length != 0).OrderBy(f => f).ToArray();
for (int ad = 0; ad < dir.Length; ad++)
{ string[] getfilearray = Directory.EnumerateFiles(dir[ad], "*.*", SearchOption.AllDirectories).ToArray();
if (getfilearray.Length == 0)
break;
if (getfilearray.Length != 0)
for (int f = 0; f < getfilearray.Length; f++)
{
string getext = Path.GetExtension(getfilearray[f]);
string fd = Path.GetDirectoryName(getfilearray[f]);
string op_path = fd.Replace(filepath, Protb.Text);
string getextension = Path.GetExtension(getfilearray[f]);
string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
string outputPath = fd.Replace(filepath, outpath);
string FNAME = Path.GetFileNameWithoutExtension(getfilearray[f]);
string fn = Path.GetDirectoryName(getfilearray[f]).Replace(filepath, outpath);
string filen = Path.Combine(outputPath, fn, FNAME + ".pdf");
string savefile = Path.Combine(op_path, filen);
string pathString = getfilearray[f];
box = Path.GetDirectoryName(getfilearray[f]);
box1 = Path.GetDirectoryName(box);
using (GdPictureDocumentConverter oConverter = new GdPictureDocumentConverter()) {
GdPictureStatus status = new GdPictureStatus();
if (Path.GetExtension(getfilearray[f]).ToUpper() == ".PDF")
{
status = oConverter.LoadFromFile(getfilearray[f], GdPicture14.DocumentFormat.DocumentFormatPDF);
}
else if (Path.GetExtension(getfilearray[f]).ToUpper() == ".TIF" || Path.GetExtension(getfilearray[f]).ToUpper() == ".TIFF")
{
status = oConverter.LoadFromFile(getfilearray[f], GdPicture14.DocumentFormat.DocumentFormatTIFF);
}
else if (Path.GetExtension(getfilearray[f]).ToUpper() == ".JPG")
{
status = oConverter.LoadFromFile(getfilearray[f], GdPicture14.DocumentFormat.DocumentFormatJPEG);
}
if (status == GdPictureStatus.OK)
{
if (!Directory.Exists(op_path))
{
Directory.CreateDirectory(op_path);
}
GrantAccess(op_path);
optPDFConform = (PdfConformance)((ComboBoxItem)cbPDFConform.SelectedItem).Tag;
status = oConverter.SaveAsPDF(savefile, optPDFConform);
if (status == GdPictureStatus.OK)
{ }
else
{ }
}
else
{ }
}
}
string BOXX = box.Replace(ip.Text, Protb.Text);
string[] Arr = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
if (MergeChk.IsChecked == true)
{ merge(Arr); }
else if (MergeChk.IsChecked == false)
{
mutliocr(Arr);
}
}
}));
}
catch (Exception ee)
{ }
return dir;
}
private string[] merge(string[] arr)
{
string box = string.Empty;
string box1 = string.Empty; string[] gg = null;
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
box = Path.GetDirectoryName(arr[0]);
box1 = Path.GetDirectoryName(box);
string dirName = Directory.GetParent(arr[0]).FullName;
string BOXFILES = Path.GetDirectoryName(dirName);
string folder = Directory.GetParent(arr[0]).FullName.Replace(Protb.Text, op.Text);
string ocrfolder = (new FileInfo(arr[0]).Directory.FullName).Replace(Protb.Text, op.Text);
string fn = Directory.GetParent(arr[0]).Name;
string filen = Path.Combine(ocrfolder, folder, fn + ".pdf");
if (!Directory.Exists(ocrfolder))
{
Directory.CreateDirectory(ocrfolder);
}
GrantAccess(ocrfolder);
using (GdPicturePDF oGdPicturePDF = new GdPicturePDF())
{
GdPictureStatus status = oGdPicturePDF.MergeDocuments(ref arr, filen);
if (status == GdPictureStatus.OK)
{ }
else
{ }
oGdPicturePDF.Dispose();
}
Directory.Delete(box, true);
string BOXX = box.Replace(Protb.Text, op.Text);//op
string[] files = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
if (MergeChk.IsChecked == true)
{ mutliocr(files); }
}));
return gg;
}
private void inbtn_Click(object sender, RoutedEventArgs e)
{
try
{ ip.Text = browseFolder(); }
catch (Exception e7)
{ MessageBox.Show("e7" + e7.Message); }
}
private void obtn_Click(object sender, RoutedEventArgs e)
{
try
{ op.Text = browseFolder(); }
catch (Exception e8)
{ MessageBox.Show("e8" + e8.Message); }
}
private void start_btn_Click(object sender, RoutedEventArgs e)
{
if (!bw.IsBusy)
{
// Cancel the asynchronous operation.
this.bw.CancelAsync();
// Disable the Cancel button.
bw.RunWorkerAsync();
start_btn.Content = "Stop";
//this.Status.Content = "Running....";
}
else
{
bw.CancelAsync();
start_btn.Content = "Start";
//this.Status.Content = "Stopped....";
}
}
private void pro_btn_Click(object sender, RoutedEventArgs e)
{
try
{ Protb.Text = browseFolder(); }
catch (Exception e10)
{ MessageBox.Show("e10" + e10.Message); }
}
private void excep_Click(object sender, RoutedEventArgs e)
{
try
{ ex_tb.Text = browseFolder(); }
catch (Exception e11)
{ MessageBox.Show("e111" + e11.Message); }
}
private void WriteLn(string text)
{
logtb.Dispatcher.BeginInvoke(new Action(() =>
{
logtb.Text += text + Environment.NewLine;
}));
log_list.Add(text);
log_cap = text + Environment.NewLine + log_cap;
using (StreamWriter sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"FileProcessing_log.txt"), false))
{
foreach (string l in log_list)
sw.WriteLine(l);
sw.Close();
}
}
}
}
The point of a BackgroundWorker is to push things off the UI thread. You do that, but then in Bw_DoWork you immediately push things back the UI thread, with this.Dispatcher.Invoke, which blocks the worker thread until the work now running on the UI thread completes.
Basically: remove that this.Dispatcher.Invoke call, and just run the code on the worker. If you need to touch the UI, then you'll need to be on the UI thread for those bits, but only those buts.
Likewise, I doubt that mutliocr should be using dispatch invoke, and it certainly shouldn't change the UI thread to being a background thread (Thread.CurrentThread.IsBackground = true;).
Your code is very very smelly and ugly. You seem to follow absolutely no naming convention at all. Locals and class members are camelCase and PascalCase and some use no casing at all and others use underscores. You should really review you code carefully with many aspects in mind and clean it up. There are some redundancies too.
A really bad habbit of yours is the excessive use of the Dispatcher. For example, you create a background thread and post the complete! work of this thread back to the Dispatcher/UI thread. A huge waste of resources and elimination of any multithreading benefit.
You don't want to put all your work on the Dispatcher. You want to offload CPU intensive eork to a background thread. You want to make use of asynchronous APIs where possible. Because you want to keep the UI responsive. Dispatcher means UI thread.
Some highly important points of interest
GrantAccess implementation is a severe security violation of user rights. Don't modify access rules. Rather filter and ignore resources where the current user is not authorized for access. What is especially critical, is that you never revert the access rights to the original state.
As a general rule: don't execute IO related code (e.g., database, HTTP streams, file IO) on a background thread. Use async APIs instead. Use threading only for CPU bound work (e.g. computations, conversions).
File has an async API you should always use. For example File.OpenRead returns a FileStream which exposes a FileStream.ReadAsnyc member. if you need more convenience when handling files like read line by line, then wrap the FileStream into a StreamReader/StreamWriter and use members like StreamReader.ReadLineAsync
To avoid Dispatcher calls, pass the required UI values to the concurent methods as argument. Better use data binding (which won't eliminate the cross threading issues writing, but would make your code more readable and eliminates Dispatcher invocation to read the values). Take alook at the refactored File_process method below. It shows how to pass UI values as argument to the converttiffpdfreducer method which is then executed on a background thread.
Consider to add cancellation support to to the longrunning converttiffpdfreducer()
Avoid calling ToArray or ToList on an IEnumerable. Those methods are finalizers that immediately execute the originally deferred LINQ queries.
Don't call ToArray or ToList on the result of EnumerateFiles and its likes. Those methods are used to improve performance as they return the filesystem objects item by item. This is especially important if you recursively iterate over the complete filesystem structure. If the filesystem tree is very deep and broad, calling ToArray will force the itereation to complete and then to return all results at once. ToArray on EnumerateFiles is like using GetFiles. You should review your complete code and refactor it properly. You always use EnumerateXYZ wrong!
"The EnumerateFiles and GetFiles methods differ as follows: When you
use EnumerateFiles, you can start enumerating the collection of names
before the whole collection is returned. When you use GetFiles, you
must wait for the whole array of names to be returned before you can
access the array. Therefore, when you are working with many files and
directories, EnumerateFiles can be more efficient."
Use data binding instead of directly accessing UI elements. This allows you to read the properties on the background thread without using the Dispatcher.
Never execute long running operation from the constructor
Never call async code from the constructor
Always keep object instantiation cheep and fast and without hidden performance/resource costs
Never catch Exception. Always catch a specialized exception type.
Don't use empty catch blocks. Either handle the exception if you can or laet it crash your application to give you a chance to fix bugs. When you swallow exceptions bugs will silently creep into your application. You will have a really hard time to discover them. Logging exceptions is not considered handling - rethrow in such case.
You don't have to close a resource explicitly if you declare the resource using the using statement. The implicit call to Dispose once the instruction pointer leaves the using scope will close the resource automatically.
Implementing all the suggestion will significantly speed up your application.
I have refactored only some of your code to show how to properly use async APIs and Task.Run instead of the BackgroundWorker. I have removed every Dispatcher invocation. Instead of direct access to UI elements in order to read their values from the background thread, I have extracted those values before invoking the concurent method and passed those prefetched values as method arguments. If you would use data binding you could read the property values directly and therefore ommit the method parameters.
The MainWindow should be shown manually from App.xaml.cs to allow asynchronous and longrunning initialization of the instance. For this pattern let the class that requires such initialization implement a public InitializeAsync method that can be awaited from the caller's context. Alternatively use Lazy<T> to defer initialization when required e.g., when initialization is depending on explicit access to members.
Although the refactored code will significantly improve the applicatoin's performance, you will have do to do some important refactoring yourself (following the pattern of the already refactored code sections).
Take a look at
InitializeAsync and WriteLnAsync to learn how to use the async file IO API.
converttiffpdfreducer to learn how to use the EnumerateFiles and EnumerateDirectories methods properly in order to significantly improve the performance.
mutliocr, merge and converttiffpdfreducer to learn how pass UI element values as argument in order to avoid Dispatcher invocations.
start_btn_Click and converttiffpdfreducer to learn how to implemnent cancellation and to guard your API against calls during an uninitialized state
App.xaml
<Application Startup="Application_Startup">
</Application>
App.xaml.cs
class App : Application
{
private async void Application_Startup(object sender, StartupEventArgs e)
{
var mainWindow = new MainWindow();
// Because InitializeAsync depends on UI elements,
// we have to wait until the Ui is loaded.
mainWindow.Loaded += OnMainWindowLoaded;
// Either call Show() before initialization or after.
// If before, ensure access to uninitialized members and resources is denied
// e.g. by querying the MainWindow.IsInitialized property in public members and event handlers.
mainWindow.Show();
}
private async void OnMainWindowLoaded(object sender, EventArgs args)
=> await mainWindow.InitializeAsync();
}
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public bool IsInitialized { get; private set; }
private bool IsBusy { get; set; }
private CancellationTokenSource CancellationTokenSource { get; set; }
public MainWindow()
{
InitializeComponent();
CancellationTokenSource = new CancellationTokenSource();
}
// Execute blocking initialization routines asynchronously
public async Task InitializeAsync()
{
if (IsInitialized)
{
return;
}
// Will execute the intesive CPU bound work on a background thread.
await File_process(Cancellationtoken.None);
string configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"path.txt");
// Use async API to read/write from/to files and other IO resources
using (FileStream configfile = File.OpenRead(configpath))
{
using (var fileReader = new StreamReader(configfile))
{
var configFileContent = new List<string>();
while (!fileReader.EndOfStream)
{
string lineOfFile = await fileReader.ReadLineAsync();
configFileContent.Add(lineOfFile);
}
if (configFileContent.Any())
{
ip.Text = configFileContent[0];
GrantAccess(configFileContent[0]);
op.Text = configFileContent[1];
GrantAccess(configFileContent[1]);
ex_tb.Text = configFileContent[2];
GrantAccess(configFileContent[2]);
Protb.Text = configFileContent[3];
GrantAccess(configFileContent[3]);
}
}
}
cbPDFConform.Items.Clear();
for (int i = 0; i < Enum.GetNames(typeof(PdfConformance)).Length - 1; i++)
{
ComboBoxItem cbi = new ComboBoxItem();
cbi.Content = Enum.GetName(typeof(PdfConformance), (PdfConformance)i);
PdfConformance test = (PdfConformance)i;
cbi.Tag = (PdfConformance)i;
cbPDFConform.Items.Add(cbi);
}
cbPDFConform.SelectedIndex = 0;
cbProcessorCount.Items.Clear();
for (int i = 1; i <= Environment.ProcessorCount; i++)
{
cbProcessorCount.Items.Add(i.ToString());
if (Environment.ProcessorCount / 2 == i) { cbProcessorCount.SelectedIndex = i - 1; }
}
LicenseManager oLicenseManager = new LicenseManager();
oLicenseManager.RegisterKEY("");
threadSyn = SynchronizationContext.Current;
IsInitialiezd = true;
}
public async Task File_process(CancellationToken cancellationToken)
{
// Read UI values to avoid Dispatcher calls from the background thread
string ipText = ip.Text;
string protbText = Protb.Text;
string opText = op.Text;
// Execute the intesive CPU bound work on a background thread.
await Task.Run(() => converttiffpdfreducer(ipText, protbText, opText, cancellationToken), cancellationToken);
}
private async Task DoWorkAsync(CancellationToken cancellationToken)
{
IsBusy = true;
using (var sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"path.txt"), false))
{
await sw.WriteLineAsync(ip.Text);
await sw.WriteLineAsync(op.Text);
await sw.WriteLineAsync(ex_tb.Text);
await sw.WriteLineAsync(Protb.Text);
}
try
{
cancellationToken.ThrowIfCancellationRequested();
var watch1 = new System.Diagnostics.Stopwatch();
watch1.Start();
// Consider to add cancellation support to File_process
await File_process(cancellationToken);
watch1.Stop();
TimeSpan ts1 = watch1.Elapsed;
ts1.ToString("mm\\:ss");
if (MergeChk.IsChecked == false)
{
value = "OCRed";
}
await WriteLnAsync("All documents have been successfully " + value + " " + ts1 + " " + DateTime.Now + " " + Environment.UserName, cancellationToken);
IsBusy = false;
}
catch (OperationCanceledException)
{
IsBusy = false;
throw;
}
}
private async Task WriteLnAsync(string text, CancellationToken cancellationToken)
{
logtb.Text += text + Environment.NewLine;
log_list.Add(text);
log_cap = text + Environment.NewLine + log_cap;
using (var sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"FileProcessing_log.txt"), false))
{
foreach (string l in log_list)
{
cancellationToken.ThrowIfCancellationRequested();
await sw.WriteLineAsync(l);
}
}
}
private async void start_btn_Click(object sender, RoutedEventArgs e)
{
if (!IsInitialized)
{
return;
}
if (IsBusy)
{
// Cancel the longrunning operation.
this.CancellationTokenSource.Cancel();
}
start_btn.Content = "Start";
try
{
await DoWorkAsync(CancellationTokenSource.Token);
}
catch (OperationCanceledException)
{
CancellationTokenSource?.Dispose();
CancellationTokenSource = new CancellationTokenSource();
}
}
private void converttiffpdfreducer(
string ipText,
string protbText,
string opText,
CancellationToken cancellationToken)
{
string[] dir = null;
string box = string.Empty;
string box1 = string.Empty;
string[] gg = null;
PdfConformance optPDFConform = PdfConformance.Unknown;
foreach (var directoryPath in Directory.EnumerateDirectories(ipText, "*.*", SearchOption.AllDirectories).Where(l => l.Length != 0))
{
cancellationToken.ThrowIfCancellationRequested();
foreach (var filePath in Directory.EnumerateFiles(directoryPath, "*.*", SearchOption.AllDirectories))
{
cancellationToken.ThrowIfCancellationRequested();
string getext = Path.GetExtension(filePath);
string fd = Path.GetDirectoryName(filePath);
string op_path = fd.Replace(ipText, protbText);
string getextension = Path.GetExtension(filePath);
string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
string outputPath = fd.Replace(ipText, protbText);
string FNAME = Path.GetFileNameWithoutExtension(filePath);
string fn = Path.GetDirectoryName(filePath).Replace(ipText, protbText);
string filen = Path.Combine(outputPath, fn, FNAME + ".pdf");
string savefile = Path.Combine(op_path, filen);
box = Path.GetDirectoryName(filePath);
box1 = Path.GetDirectoryName(box);
using (GdPictureDocumentConverter oConverter = new GdPictureDocumentConverter())
{
GdPictureStatus status = new GdPictureStatus();
if (Path.GetExtension(filePath).ToUpper() == ".PDF")
{
status = oConverter.LoadFromFile(filePath, GdPicture14.DocumentFormat.DocumentFormatPDF);
}
else if (Path.GetExtension(filePath).ToUpper() == ".TIF" || Path.GetExtension(filePath).ToUpper() == ".TIFF")
{
status = oConverter.LoadFromFile(filePath, GdPicture14.DocumentFormat.DocumentFormatTIFF);
}
else if (Path.GetExtension(filePath).ToUpper() == ".JPG")
{
status = oConverter.LoadFromFile(filePath, GdPicture14.DocumentFormat.DocumentFormatJPEG);
}
if (status == GdPictureStatus.OK)
{
if (!Directory.Exists(op_path))
{
Directory.CreateDirectory(op_path);
}
GrantAccess(op_path);
optPDFConform = (PdfConformance)((ComboBoxItem)cbPDFConform.SelectedItem).Tag;
status = oConverter.SaveAsPDF(savefile, optPDFConform);
if (status == GdPictureStatus.OK)
{ }
else
{ }
}
else
{ }
}
}
}
string BOXX = box.Replace(ipText, protbText);
// TODO::Refactor 'merge' and replace 'ToArray' with 'foreach'
string[] Arr = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
if (MergeChk.IsChecked == true)
{ merge(Arr, protbText); }
else if (MergeChk.IsChecked == false)
{
mutliocr(Arr);
}
}
private string[] merge(string[] arr, string protbText, string opText)
{
string box = string.Empty;
string box1 = string.Empty; string[] gg = null;
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
box = Path.GetDirectoryName(arr[0]);
box1 = Path.GetDirectoryName(box);
string dirName = Directory.GetParent(arr[0]).FullName;
string BOXFILES = Path.GetDirectoryName(dirName);
string folder = Directory.GetParent(arr[0]).FullName.Replace(protbText, opText);
string ocrfolder = (new FileInfo(arr[0]).Directory.FullName).Replace(protbText, opText);
string fn = Directory.GetParent(arr[0]).Name;
string filen = Path.Combine(ocrfolder, folder, fn + ".pdf");
if (!Directory.Exists(ocrfolder))
{
Directory.CreateDirectory(ocrfolder);
}
GrantAccess(ocrfolder);
using (GdPicturePDF oGdPicturePDF = new GdPicturePDF())
{
GdPictureStatus status = oGdPicturePDF.MergeDocuments(ref arr, filen);
if (status == GdPictureStatus.OK)
{ }
else
{ }
oGdPicturePDF.Dispose();
}
Directory.Delete(box, true);
string BOXX = box.Replace(protbText, opText);//op
string[] files = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
if (MergeChk.IsChecked == true)
{ mutliocr(files, protbText, opText); }
}));
return gg;
}
private string[] mutliocr(string[] arr, string protbText, string opText)
{
string box = string.Empty;
string box1 = string.Empty;
try
{
string filepath = string.Empty;
if (MergeChk.IsChecked == true)
{ filepath = opText; }
else if (MergeChk.IsChecked == false)
{ filepath = protbText; }
System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
{
Thread.CurrentThread.IsBackground = true;
var watch2 = new System.Diagnostics.Stopwatch();
watch2.Start();
string[] getfilearray = arr;
for (int f = 0; f < getfilearray.Length; f++)
{
string dirName = Directory.GetParent(getfilearray[f]).FullName;
string folder = Directory.GetParent(getfilearray[f]).FullName;
box = Path.GetDirectoryName(getfilearray[f]);
box1 = Path.GetDirectoryName(box);
string getextension = Path.GetExtension(getfilearray[f]);
string[] newF = Directory.EnumerateFiles(dirName, "*.*", SearchOption.AllDirectories).ToArray();
string FN = Directory.GetParent(getfilearray[f]).Name;
string ocrfolder = (new FileInfo(getfilearray[f]).Directory.FullName);
string filen = Path.Combine(ocrfolder, folder, FN + "-ocr" + getextension);
string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
if (!Directory.Exists(ocrfolder))
{
Directory.CreateDirectory(ocrfolder);
}
GrantAccess(ocrfolder);
GdPicturePDF oGdPicturePDF = new GdPicturePDF();
oGdPicturePDF.OcrPagesDone += OcrPagesDone;
void OcrPagesDone(GdPictureStatus status1)
{
if (oGdPicturePDF.SaveToFile(filen) == GdPictureStatus.OK)
{ }
else
MessageBox.Show("PDF: The OCR-ed file has failed to save. Status: " + oGdPicturePDF.GetStat().ToString());
}
GdPictureStatus status = GdPictureStatus.OK;
if (oGdPicturePDF.LoadFromFile(getfilearray[f], false) == GdPictureStatus.OK)
if (status == GdPictureStatus.OK)
{
if (oGdPicturePDF.OcrPages_4("*", 0, "eng", dict, "", 300, OCRMode.FavorSpeed, 1, true) == GdPictureStatus.OK)
if (status == GdPictureStatus.OK)
{ }
else
{ MessageBox.Show("PDF: The OCR process has failed. Status: " + status.ToString()); }
}
else
{ MessageBox.Show("PDF: The PDF file has failed to load. Status: " + status.ToString()); }
oGdPicturePDF.Dispose();
GrantAccess(getfilearray[f]);
File.Delete(getfilearray[f]);
watch2.Stop();
TimeSpan ts2 = watch2.Elapsed;
ts2.ToString("mm\\:ss");
WriteLn(" OCR pages " + filen.Replace(opText, "") + " " + ts2 + " " + DateTime.Now);
}
if (MergeChk.IsChecked == true)
{
foreach (string str in Directory.EnumerateFiles(opText, "*.pdf", SearchOption.AllDirectories).ToArray())
{
if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4) + ".pdf"));
}
}
if (MergeChk.IsChecked == false)
{
FileSystem.MoveDirectory(protbText, opText, UIOption.AllDialogs);
Directory.CreateDirectory(protbText);
string FF = string.Empty;
foreach (string str in Directory.EnumerateFiles(opText, "*.pdf", SearchOption.AllDirectories))
{
if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4) + ".pdf"));
}
}
}));
}
catch (Exception mul)
{
}
return arr;
}
}
I have an news aggregator and in debug i have the following:
Skipped 675 frames! The application may be doing too much work on its main thread.
I am loading only from 12 sites. Is there a way to to do all this loading in background without the whole app freezing?
EDIT:
Method to get one news
public async static Task<NewsContent> oneNews(string category,string site)
{
if(sites.Count==0)
addElements();
GetNews gn = new GetNews(site,false);
Random rn = new Random();
var s = await gn.news(rn.Next(0,2));
return s;
}
The GetNews class:
class GetNews
{
string url;
bool isMultiple;
public GetNews(string url,bool isMultiple)
{
this.url = url;
this.isMultiple = isMultiple;
}
public async Task<NewsContent> news(int i)
{
List<NewsContent> feedItemsList = new List<NewsContent>();
try
{
WebRequest webRequest = WebRequest.Create(url);
WebResponse webResponse = webRequest.GetResponse();
Stream stream = webResponse.GetResponseStream();
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(stream);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDocument.NameTable);
nsmgr.AddNamespace("dc", xmlDocument.DocumentElement.GetNamespaceOfPrefix("dc"));
nsmgr.AddNamespace("content", xmlDocument.DocumentElement.GetNamespaceOfPrefix("content"));
XmlNodeList itemNodes = xmlDocument.SelectNodes("rss/channel/item");
NewsContent feedItem = new NewsContent();
if (itemNodes[i].SelectSingleNode("title") != null)
{
feedItem.title = itemNodes[i].SelectSingleNode("title").InnerText;
}
if (itemNodes[i].SelectSingleNode("link") != null)
{
feedItem.url = itemNodes[i].SelectSingleNode("link").InnerText;
}
if (itemNodes[i].SelectSingleNode("pubDate") != null)
{
var time = itemNodes[i].SelectSingleNode("pubDate").InnerText;
feedItem.time = getHour(time);
}
if (itemNodes[i].SelectSingleNode("description") != null)
{
feedItem.desc = itemNodes[i].SelectSingleNode("description").InnerText;
}
if (itemNodes[i].SelectSingleNode("content:encoded", nsmgr) != null)
{
feedItem.content = itemNodes[i].SelectSingleNode("content:encoded", nsmgr).InnerText;
}
else
{
feedItem.content = feedItem.desc;
}
feedItem.imageURL = getImage(feedItem.content);
var sourcename = url.Split(new[] { "//" }, StringSplitOptions.None)[1];
feedItem.newsSource = sourcename.Split(new[] { "/" }, StringSplitOptions.None)[0];
if (feedItem.content.Contains("<p>"))
{
var shortContent = feedItem.content.Split(new[] { "<p>" }, StringSplitOptions.None)[1];
string finalShortContent = "";
for (int ii = 0; ii < shortContent.Length; ii++)
{
if (ii > 200 && shortContent[ii].Equals(' '))
break;
while (shortContent[ii].Equals('<') || shortContent[ii].Equals('p') || shortContent[ii].Equals('/') || shortContent[ii].Equals('>'))
ii++;
try
{
finalShortContent += shortContent[ii];
}
catch (Exception e)
{
break;
}
}
finalShortContent += "...";
feedItem.shortcontent = finalShortContent;
}
return feedItem;
}
catch (Exception e)
{
return null;
}
}
string getImage(string full)
{
try
{
var code = full.Split(new[] { "src=\"" }, StringSplitOptions.None)[1];
var fin = code.Split(new[] { "\"" }, StringSplitOptions.None)[0];
return fin;
}
catch(Exception e)
{
return null;
}
}
List<int> getHour(string full)
{
try
{
List<int> smh = new List<int>();
var ph = full.Split(new[] { "2020 " }, StringSplitOptions.None)[1];
var hour = ph.Split(new[] { ":" }, StringSplitOptions.None);
smh.Add(Int32.Parse(hour[0]));
smh.Add(Int32.Parse(hour[1]));
var second = hour[2].Split(new[] { " " }, StringSplitOptions.None)[0];
smh.Add(Int32.Parse(second));
return smh;
}catch(Exception)
{
return null;
}
}
}
Try this. It should put the function in another thread
await Task.Run(async () =>
{
//function
});
This is my code which create PDF of a dwg file but it gives me error near MultiSheetPdf. Please give me the solution for same.
I thought that linking is the problem but I am not able to identify please suggest me the solution.
namespace Plottings
{
public class MultiSheetsPdf
{
private string dwgFile, pdfFile, dsdFile, outputDir;
private int sheetNum;
private IEnumerable<Layout> layouts;
private const string LOG = "publish.log";
public MultiSheetsPdfPlot(string pdfFile, IEnumerable<Layout> layouts)
{
Database db = HostApplicationServices.WorkingDatabase;
this.dwgFile = db.Filename;
this.pdfFile = pdfFile;
this.outputDir = Path.GetDirectoryName(this.pdfFile);
this.dsdFile = Path.ChangeExtension(this.pdfFile, "dsd");
this.layouts = layouts;
}
public void Publish()
{
if (TryCreateDSD())
{
Publisher publisher = AcAp.Publisher;
PlotProgressDialog plotDlg = new PlotProgressDialog(false, this.sheetNum, true);
publisher.PublishDsd(this.dsdFile, plotDlg);
plotDlg.Destroy();
File.Delete(this.dsdFile);
}
}
private bool TryCreateDSD()
{
using (DsdData dsd = new DsdData())
using (DsdEntryCollection dsdEntries = CreateDsdEntryCollection(this.layouts))
{
if (dsdEntries == null || dsdEntries.Count <= 0) return false;
if (!Directory.Exists(this.outputDir))
Directory.CreateDirectory(this.outputDir);
this.sheetNum = dsdEntries.Count;
dsd.SetDsdEntryCollection(dsdEntries);
dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
dsd.SheetType = SheetType.MultiDwf;
dsd.NoOfCopies = 1;
dsd.DestinationName = this.pdfFile;
dsd.IsHomogeneous = false;
dsd.LogFilePath = Path.Combine(this.outputDir, LOG);
PostProcessDSD(dsd);
return true;
}
}
private DsdEntryCollection CreateDsdEntryCollection(IEnumerable<Layout> layouts)
{
DsdEntryCollection entries = new DsdEntryCollection();
foreach (Layout layout in layouts)
{
DsdEntry dsdEntry = new DsdEntry();
dsdEntry.DwgName = this.dwgFile;
dsdEntry.Layout = layout.LayoutName;
dsdEntry.Title = Path.GetFileNameWithoutExtension(this.dwgFile) + "-" + layout.LayoutName;
dsdEntry.Nps = layout.TabOrder.ToString();
entries.Add(dsdEntry);
}
return entries;
}
private void PostProcessDSD(DsdData dsd)
{
string str, newStr;
string tmpFile = Path.Combine(this.outputDir, "temp.dsd");
dsd.WriteDsd(tmpFile);
using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
using (StreamWriter writer = new StreamWriter(this.dsdFile, false, Encoding.Default))
{
while (!reader.EndOfStream)
{
str = reader.ReadLine();
if (str.Contains("Has3DDWF"))
{
newStr = "Has3DDWF=0";
}
else if (str.Contains("OriginalSheetPath"))
{
newStr = "OriginalSheetPath=" + this.dwgFile;
}
else if (str.Contains("Type"))
{
newStr = "Type=6";
}
else if (str.Contains("OUT"))
{
newStr = "OUT=" + this.outputDir;
}
else if (str.Contains("IncludeLayer"))
{
newStr = "IncludeLayer=TRUE";
}
else if (str.Contains("PromptForDwfName"))
{
newStr = "PromptForDwfName=FALSE";
}
else if (str.Contains("LogFilePath"))
{
newStr = "LogFilePath=" + Path.Combine(this.outputDir, LOG);
}
else
{
newStr = str;
}
writer.WriteLine(newStr);
}
}
File.Delete(tmpFile);
}
[CommandMethod("PlotPdf")]
public void PlotPdf()
{
Database db = HostApplicationServices.WorkingDatabase;
short bgp = (short)Application.GetSystemVariable("BACKGROUNDPLOT");
try
{
Application.SetSystemVariable("BACKGROUNDPLOT", 0);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
List<Layout> layouts = new List<Layout>();
DBDictionary layoutDict =
(DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
foreach (DBDictionaryEntry entry in layoutDict)
{
if (entry.Key != "Model")
{
layouts.Add((Layout)tr.GetObject(entry.Value, OpenMode.ForRead));
}
}
layouts.Sort((l1, l2) => l1.TabOrder.CompareTo(l2.TabOrder));
string filename = Path.ChangeExtension(db.Filename, "pdf");
MultiSheetsPdf plotter = new MultiSheetsPdf(filename, layouts);
plotter.Publish();
tr.Commit();
}
}
catch (System.Exception e)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
}
finally
{
Application.SetSystemVariable("BACKGROUNDPLOT", bgp);
}
}
}
}
Here you go: (Try to note and understand the difference between your version and this version)
namespace Plottings
{
public class MultiSheetsPdf
{
private string dwgFile, pdfFile, dsdFile, outputDir;
private int sheetNum;
private IEnumerable<Layout> layouts;
private const string LOG = "publish.log";
public MultiSheetsPdf(){}
public MultiSheetsPdf(string pdfFile, IEnumerable<Layout> layouts)
{
Database db = HostApplicationServices.WorkingDatabase;
this.dwgFile = db.Filename;
this.pdfFile = pdfFile;
this.outputDir = Path.GetDirectoryName(this.pdfFile);
this.dsdFile = Path.ChangeExtension(this.pdfFile, "dsd");
this.layouts = layouts;
}
public void Publish()
{
if (TryCreateDSD())
{
Publisher publisher = AcAp.Publisher;
PlotProgressDialog plotDlg = new PlotProgressDialog(false, this.sheetNum, true);
publisher.PublishDsd(this.dsdFile, plotDlg);
plotDlg.Destroy();
File.Delete(this.dsdFile);
}
}
private bool TryCreateDSD()
{
using (DsdData dsd = new DsdData())
using (DsdEntryCollection dsdEntries = CreateDsdEntryCollection(this.layouts))
{
if (dsdEntries == null || dsdEntries.Count <= 0) return false;
if (!Directory.Exists(this.outputDir))
Directory.CreateDirectory(this.outputDir);
this.sheetNum = dsdEntries.Count;
dsd.SetDsdEntryCollection(dsdEntries);
dsd.SetUnrecognizedData("PwdProtectPublishedDWF", "FALSE");
dsd.SetUnrecognizedData("PromptForPwd", "FALSE");
dsd.SheetType = SheetType.MultiDwf;
dsd.NoOfCopies = 1;
dsd.DestinationName = this.pdfFile;
dsd.IsHomogeneous = false;
dsd.LogFilePath = Path.Combine(this.outputDir, LOG);
PostProcessDSD(dsd);
return true;
}
}
private DsdEntryCollection CreateDsdEntryCollection(IEnumerable<Layout> layouts)
{
DsdEntryCollection entries = new DsdEntryCollection();
foreach (Layout layout in layouts)
{
DsdEntry dsdEntry = new DsdEntry();
dsdEntry.DwgName = this.dwgFile;
dsdEntry.Layout = layout.LayoutName;
dsdEntry.Title = Path.GetFileNameWithoutExtension(this.dwgFile) + "-" + layout.LayoutName;
dsdEntry.Nps = layout.TabOrder.ToString();
entries.Add(dsdEntry);
}
return entries;
}
private void PostProcessDSD(DsdData dsd)
{
string str, newStr;
string tmpFile = Path.Combine(this.outputDir, "temp.dsd");
dsd.WriteDsd(tmpFile);
using (StreamReader reader = new StreamReader(tmpFile, Encoding.Default))
using (StreamWriter writer = new StreamWriter(this.dsdFile, false, Encoding.Default))
{
while (!reader.EndOfStream)
{
str = reader.ReadLine();
if (str.Contains("Has3DDWF"))
{
newStr = "Has3DDWF=0";
}
else if (str.Contains("OriginalSheetPath"))
{
newStr = "OriginalSheetPath=" + this.dwgFile;
}
else if (str.Contains("Type"))
{
newStr = "Type=6";
}
else if (str.Contains("OUT"))
{
newStr = "OUT=" + this.outputDir;
}
else if (str.Contains("IncludeLayer"))
{
newStr = "IncludeLayer=TRUE";
}
else if (str.Contains("PromptForDwfName"))
{
newStr = "PromptForDwfName=FALSE";
}
else if (str.Contains("LogFilePath"))
{
newStr = "LogFilePath=" + Path.Combine(this.outputDir, LOG);
}
else
{
newStr = str;
}
writer.WriteLine(newStr);
}
}
File.Delete(tmpFile);
}
[CommandMethod("PlotPdf")]
public void PlotPdf()
{
Database db = HostApplicationServices.WorkingDatabase;
short bgp = (short)Application.GetSystemVariable("BACKGROUNDPLOT");
try
{
Application.SetSystemVariable("BACKGROUNDPLOT", 0);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
List<Layout> layouts = new List<Layout>();
DBDictionary layoutDict =
(DBDictionary)db.LayoutDictionaryId.GetObject(OpenMode.ForRead);
foreach (DBDictionaryEntry entry in layoutDict)
{
if (entry.Key != "Model")
{
layouts.Add((Layout)tr.GetObject(entry.Value, OpenMode.ForRead));
}
}
layouts.Sort((l1, l2) => l1.TabOrder.CompareTo(l2.TabOrder));
string filename = Path.ChangeExtension(db.Filename, "pdf");
MultiSheetsPdf plotter = new MultiSheetsPdf(filename, layouts);
plotter.Publish();
tr.Commit();
}
}
catch (System.Exception e)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\nError: {0}\n{1}", e.Message, e.StackTrace);
}
finally
{
Application.SetSystemVariable("BACKGROUNDPLOT", bgp);
}
}
}
}
Heads up. The method, PostProcessDSD, tests are too generic. Client contacted me complaining that one of his files was not plotting. It was named "SOUTH". The test for "OUT" in the string caused the issue. No errors were thrown. Just a good ol' fashion mystery.
Change all tests to include the "=". ie else if (str.Contains("OUT=")) { ...
I want to pass real time signals from emotive to octave.
I tried to write a c# wrapper for octave. Here is the code.
namespace LibSharpTave {
public class Octave {
Process OctaveProcess { get; set; }
private string OctaveEchoString { get; set; }
public Octave(string PathToOctaveBinaries) {
StartOctave(PathToOctaveBinaries, false);
}
public Octave(string PathToOctaveBinaries, bool CreateWindow) {
StartOctave(PathToOctaveBinaries, CreateWindow);
}
string ptob;
bool cw;
private void StartOctave(string PathToOctaveBinaries, bool CreateWindow) {
ptob = PathToOctaveBinaries;
cw = CreateWindow;
this.OctaveEchoString = Guid.NewGuid().ToString();
OctaveProcess = new Process();
ProcessStartInfo pi = new ProcessStartInfo();
if (PathToOctaveBinaries[PathToOctaveBinaries.Length - 1] != '\\')
PathToOctaveBinaries = PathToOctaveBinaries + "\\";
pi.FileName = PathToOctaveBinaries + "octave.exe";
pi.RedirectStandardInput = true;
pi.RedirectStandardOutput = true;
pi.RedirectStandardError = true;
pi.UseShellExecute = false;
pi.CreateNoWindow = !CreateWindow;
pi.Verb = "open";
//
pi.WorkingDirectory = ".";
OctaveProcess.StartInfo = pi;
OctaveProcess.Start();
OctaveProcess.OutputDataReceived += new DataReceivedEventHandler(OctaveProcess_OutputDataReceived);
OctaveProcess.BeginOutputReadLine();
OctaveEntryText = ExecuteCommand(null);
//OctaveProcess.OutputDataReceived += new DataReceivedEventHandler(Oc
}
public double GetScalar(string scalar) {
string rasp = ExecuteCommand(scalar, 30000);
string val = rasp.Substring(rasp.LastIndexOf("\\") + 1).Trim();
return double.Parse(val);
}
public double[] GetVector(string vector) {
string rasp = ExecuteCommand(vector, 30000);
string[] lines = rasp.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
int i = 0;
//catam urmatorul entry
List<double> data = new List<double>();
while (i != lines.Length) {
string line = lines[i];
if (line.Contains("through") || line.Contains("and")) {
i++;
line = lines[i];
string[] dataS = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
for (int k = 0; k < dataS.Length; k++) {
data.Add(double.Parse(dataS[k]));
}
}
i++;
}
//caz special in care a pus toate rezultatele pe o singura linie
if (data.Count == 0) {
string[] dataS = lines[lines.Length - 1].Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
if (dataS.Length != 0)
for (int k = 0; k < dataS.Length; k++) {
data.Add(double.Parse(dataS[k]));
}
}
return data.ToArray();
}
public double[][] GetMatrix(string matrix) {
//string rasp = ExecuteCommand(matrix);
//aflam numarul de randuri
string rasp = ExecuteCommand(matrix + "(:,1)", 30000);
string[] lines = rasp.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
double[][] mat = new double[lines.Length - 1][];
for (int i = 0; i < mat.Length; i++) {
mat[i] = GetVector(matrix + "(" + (i + 1) + ",:)");
}
return mat;
}
StringBuilder SharedBuilder = new StringBuilder();
ManualResetEvent OctaveDoneEvent = new ManualResetEvent(false);
public string OctaveEntryText { get; internal set; }
public void WorkThread(object o) {
string command = (string)o;
SharedBuilder.Clear();
OctaveDoneEvent.Reset();
if (command != null) {
OctaveProcess.StandardInput.WriteLine(command);
}
//ca sa avem referinta pentru output
OctaveProcess.StandardInput.WriteLine("\"" + OctaveEchoString + "\"");
OctaveDoneEvent.WaitOne();
}
public string ExecuteCommand(string command, int timeout) {
if (OctaveProcess.HasExited) {
StartOctave(ptob, cw);
if (OctaveRestarted != null) OctaveRestarted(this, EventArgs.Empty);
}
exitError = false;
Thread tmp = new Thread(new ParameterizedThreadStart(WorkThread));
tmp.Start(command);
if (!tmp.Join(timeout)) {
tmp.Abort();
throw new Exception("Octave timeout");
}
if (exitError) {
throw new Exception(errorMessage);
}
return SharedBuilder.ToString();
}
public string ExecuteCommand(string command) {
// Thread tmp = new Thread(new ParameterizedThreadStart(WorkThread));
// tmp.Start(command);
// tmp.Join();
// return SharedBuilder.ToString();
if (OctaveProcess.HasExited)
{
OctaveProcess.Start();
}
SharedBuilder.Clear();
if (command != null)
{
OctaveProcess.StandardInput.WriteLine(command);
OctaveDoneEvent.Reset();
OctaveDoneEvent.WaitOne();
return SharedBuilder.ToString();
}
Octave octave = new Octave(#"c:\software\Octave-3.6.4",false);
octave.ExecuteCommand("a=[1,2;3,4];");
octave.ExecuteCommand("result=a;");
double[][] m = octave.GetMatrix("result");
}
bool exitError = false;
string errorMessage = null;
void OctaveProcess_OutputDataReceived(object sender, DataReceivedEventArgs e) {
if (e.Data == null) {
SharedBuilder.Clear();
//errorMessage = OctaveProcess.StandardError.ReadToEnd();
SharedBuilder.Append("Octave has exited with the following error message: \r\n" + errorMessage);
//exitError = true;
OctaveDoneEvent.Set();
return;
}
if (e.Data.Trim() == "ans = " + OctaveEchoString)
OctaveDoneEvent.Set();
else
SharedBuilder.Append(e.Data + "\r\n");
}
public event OctaveRestartedEventHandler OctaveRestarted;
public delegate void OctaveRestartedEventHandler(object sender, EventArgs e);
}
//custom class
// void OctaveProcess_OutputDataReceived (object sender, DataReceivedeEventArgs e)
/*{
if (e.data == null)
{
SharedBuilder.Clear();
SharedBuilder.Append("Octave has exited with the following error message: \r\n" + OctaveProcess.StandardError.ReadToEnd());
OctaveDoneEvent.Set();
return;
}
if (e.data.Trim == "ans =" + OctaveEchoString())
OctaveDoneEvent.set();
else
SharedBuilder.Append(e.Data + "\r\n");
}*/
}
And it is returning the error: "Not all code paths return a value".
How can I fix this error?
Your ExecuteCommand function should return a string, but doesn't. This is the ExecuteCommand overload that accepts one argument.
This function has string as return type but does not return anything when if (command != null) statement is false -
public string ExecuteCommand(string command) {
// Thread tmp = new Thread(new ParameterizedThreadStart(WorkThread));
// tmp.Start(command);
// tmp.Join();
// return SharedBuilder.ToString();
if (OctaveProcess.HasExited)
{
OctaveProcess.Start();
}
SharedBuilder.Clear();
if (command != null)
{
OctaveProcess.StandardInput.WriteLine(command);
OctaveDoneEvent.Reset();
OctaveDoneEvent.WaitOne();
return SharedBuilder.ToString();
}
Octave octave = new Octave(#"c:\software\Octave-3.6.4",false);
octave.ExecuteCommand("a=[1,2;3,4];");
octave.ExecuteCommand("result=a;");
double[][] m = octave.GetMatrix("result");
//**** The Error is here *****
//return a string here
}
Return a string at the mention section. I highlighted in the comment as - //**** The Error is here *****
Your
public string ExecuteCommand(string command) {
has no return statement even though you specified return type string.
Either return some string or make its return type void as in :
public void ExecuteCommand(string command) {
I am sharing a static array between a number of System.Threading.Timer simultaneously. This array is accessed only by the first timer thread & second timer will not accessed this array. An exception is displayed: "error can not evaluate expression a native frame is on top of the call stack in c#"
please reply
project code:
public partial class OPC_server : DevExpress.XtraEditors.XtraForm
{
private System.Threading.Timer timer1;
private System.Threading.Timer timer2;
parameter param = new parameter();//another class
private static readonly object myLockHolder = new object();
private static readonly object myLockHolder1 = new object();
public static OpcServer[] _opcServer;
private void OPC_server_Load(object sender, EventArgs e)
{
getconnectedOPC();
}
public void getconnectedOPC()
{
ds = opcconn.GetOPCServerInfo();
int i=0;
DataTable dtOPC=new DataTable();
if (ds.Tables[0].Rows.Count != 0 || ds.Tables[0] != null)
{
dtOPC = ds.Tables[0].Copy();
_opcServer = new OpcServer[dtOPC.Rows.Count];
TimeSpan delayTime = new TimeSpan(0, 0, 1);
TimeSpan intervalTime = new TimeSpan(0, 0, 0, 0, 450);
foreach (DataRow row in dtOPC.Rows)
{
if (i <= dtOPC.Rows.Count)
{
//connetion(row);
getconnect(i, row, dtOPC.Rows.Count);
i++;
}
}
connetion(dtOPC.Rows.Count);
}
}
//connecting the server
public void getconnect(int conn, DataRow r,int rows)
{
DataSet ds2=new DataSet();
DataTable dt2 = new DataTable();
try
{
string machinename = Convert.ToString(r["OPCIPAddress"]);
string servername = Convert.ToString(r["OPCName"]);
_opcServer[conn] = new OpcServer();
int i = _opcServer[conn].Connect(machinename, servername);
if (i == 0)
{
opcconn.update("true", servername);
writelog(servername, "connected");
}
else
{
opcconn.update("false", servername);
writelog(servername, "disconnected");
}
}
catch (OPCException e)
{
servername = Convert.ToString(r["OPCName"]);
opcconn.update("false", servername);
writelog(servername, e.Message.ToString());
}
catch (ApplicationException e)
{
servername = Convert.ToString(r["OPCName"]);
opcconn.update("false", servername);
writelog(servername, "No instance server");
}
}
public void connetion(object state)
{
int k ,i,q=0;
k = (System.Int32)state;
DataSet dsgroup=new DataSet();
while(j < k)
{
try
{
bool val;
HRESULTS re;
SrvStatus status;
DateTime dt;
i = _opcServer[j].GetStatus(out status);
if (HRESULTS.Failed(i))
{
try
{
opcconn.update("false", _opcServer[j].ServerName.ToString());
string IP = opcconn.search(_opcServer[j].ServerName.ToString());
_opcServer[j].Connect(IP, _opcServer[j].ServerName.ToString());
opcconn.update("true", _opcServer[j].ServerName.ToString());
j++;
}
catch
{
opcconn.update("false", _opcServer[j].ServerName.ToString());
j++;
}
}
else
{
val = HRESULTS.Succeeded(i);
dsgroup = grpclass.getgroupinfo(j + 1);
if (dsgroup.Tables[0].Rows.Count != 0)
{
grpdt = new DataTable();
grpdt = dsgroup.Tables[0].Copy();
foreach (DataRow Row in grpdt.Rows)
{
if (groupcnt <= 128)
{
if (cntgroup < grpdt.Rows.Count)
{
grp = _opcServer[j].AddGroup((Convert.ToString(Row["GroupName"])), (Convert.ToBoolean(Row["setactive"])), (Convert.ToInt32(Row["refreshRate"])), 1);
ds1 = param.getparameter1(Convert.ToInt32(Row["groupID"]));
if (ds1.Tables[0].Rows.Count != 0)
{
dt1 = ds1.Tables[0].Copy();
int tq = 0;
item1 = new OPCItemDef[dt1.Rows.Count];
int clienthandle = 1;
foreach (DataRow r in dt1.Rows)
{
if (tq < item1.Length)
{
item1[tq] = new OPCItemDef(Convert.ToString(r["param_ID"]), Convert.ToBoolean(r["active"]), clienthandle, VarEnum.VT_EMPTY);
++clienthandle;
tq++;
}
}
int y = grp.AddItems(item1, out addRslt);
// thread started like each group assign one thread
OPCthread(Row, groupcnt);
groupcnt++;
cntgroup++;
}
}
}
}
}
cntgroup = 0;
j++;
}
}
catch (OPCException)
{
string servername = opcconn.getserver(j + 1);
string IPadd = opcconn.search(servername);
_opcServer[j].Connect(IPadd, servername);
}
catch (IndexOutOfRangeException)
{
j = 0;
}
catch (InvalidCastException e)
{
try
{
// writelog1(_opcServer[j].ServerName.ToString(), "disconnected");
opcconn.update("false", _opcServer[j].ServerName.ToString());
string IP = opcconn.search(_opcServer[j].ServerName.ToString());
_opcServer[j].Connect(IP, _opcServer[j].ServerName.ToString());
opcconn.update("true", _opcServer[j].ServerName.ToString());
j++;
}
catch
{
// writelog1(_opcServer[j].ServerName.ToString(), "connection failed");
opcconn.update("true", _opcServer[j].ServerName.ToString());
j++;
}
}
catch (ArgumentOutOfRangeException)
{
j = 0;
}
catch (NullReferenceException)
{
try
{
// writelog1("server'" + j + "' ", "no server instance");
OPC1 = opcconn.getserver(j + 1);
string IPA = opcconn.search(OPC1);
_opcServer[j].Connect(IPA, OPC1);
opcconn.update("true", OPC1);
writelog(OPC1, "connected");
j++;
}
catch (OPCException e)
{
opcconn.update("false", OPC1);
writelog(OPC1, e.Message.ToString());
j++;
}
catch (ApplicationException e)
{
opcconn.update("false", OPC1);
writelog(OPC1, "No instance server");
j++;
}
}
}
}
public void OPCthread(DataRow r2,int timerinfo)
{
if (timerinfo == 0)
{
int rer = Convert.ToInt32(r2["refreshRate"]);//at least 1 second
TimeSpan dueTime = new TimeSpan(0, 0,0,0,rer);
TimeSpan interval = new TimeSpan(0, 0, 0 ,0 ,rer);
timer1 = new System.Threading.Timer(register, r2, dueTime,interval);
}
else if (timerinfo == 1)
{
TimeSpan dueTime;
TimeSpan interval;
int rer1 = Convert.ToInt32(r2["refreshRate"]);
dueTime = new TimeSpan(0, 0, 0, 0, rer1);
interval = new TimeSpan(0, 0, 0, 0, rer1);
timer2 = new System.Threading.Timer(register1, r2, dueTime, interval);
}
}
public void register(object row1)
{
try
{
lock (myLockHolder)
{
int cnt = 0, cnt1 = 0;
ItemValue[] rVals;
OPCItemDef[] item;
OpcServer srv = new OpcServer();
string[] array;
//SrvStatus status1;
DataSet paramds = new DataSet();
DataTable paramdt = new DataTable();
DataRow dt = (System.Data.DataRow)row1;
int serverID = Convert.ToInt32(dt["OPCServerID"]);
paramds = param.getparameter(Convert.ToInt32(dt["groupID"]));
if (Convert.ToBoolean(dt["setactive"]) == true)
{
if (paramds != null && paramds.Tables[0].Rows.Count != 0)
{
paramdt = paramds.Tables[0].Copy();
int tq = 0;
item = new OPCItemDef[paramdt.Rows.Count];
int clienthandle = 1;
foreach (DataRow r in paramdt.Rows)
{
if (tq < item.Length)
{
item[tq] = new OPCItemDef(Convert.ToString(r["param_ID"]), Convert.ToBoolean(r["active"]), clienthandle, VarEnum.VT_EMPTY);
++clienthandle;
tq++;
}
}
array = new string[item.Length];
cnt1 = 0;
while (cnt1 < array.Length)
{
array[cnt1] = item[cnt1].ItemID;
cnt1++;
}
rVals = _opcServer[serverID - 1].Read(array, Convert.ToInt32(dt["refreshRate"]));
//this line i got the exception when i checking the value of the _opcserver varible in locals the it will be display as "error can not evaluate expression a native frame is on top of the call stack in c#" & thread will stop the execution.
param.update(rVals, Convert.ToInt32(dt["groupID"]));
}
}
}
}
catch (ThreadAbortException) { }
finally { }
}
public void register1(object row2)
{
try
{
lock (myLockHolder1)
{
int cnt = 0, cnt11 = 0;
ItemValue[] rVals1;
OPCItemDef[] item1;
OpcServer srv1 = new OpcServer();
string[] array1;
DataSet paramds1 = new DataSet();
DataTable paramdt1 = new DataTable();
DataRow dt1 = (System.Data.DataRow)row2;
int serverID1 = Convert.ToInt32(dt1["OPCServerID"]);
// Boolean gstatus = grpclass.getstatus(Convert.ToInt32(dt["groupID"]));
paramds1 = param.getparameter2(Convert.ToInt32(dt1["groupID"]));
if (Convert.ToBoolean(dt1["setactive"]) == true)
{
if (paramds1 != null)
{
paramdt1 = paramds1.Tables[0].Copy();
int tq1 = 0;
item1 = new OPCItemDef[paramdt1.Rows.Count];
int clienthandle1 = 1;
foreach (DataRow r in paramdt1.Rows)
{
if (tq1 < item1.Length)
{
item1[tq1] = new OPCItemDef(Convert.ToString(r["param_ID"]), Convert.ToBoolean(r["active"]), clienthandle1, VarEnum.VT_EMPTY);
clienthandle1++;
tq1++;
}
}
array1 = new string[item1.Length];
cnt11 = 0;
while (cnt11 < array1.Length)
{
array1[cnt11] = item1[cnt11].ItemID;
cnt11++;
}
rvals = _opcServer[serverID1 - 1].Read(array1, Convert.ToInt32(dt1["refreshRate"]));//this line i got the exception when i checking the value of the _opcserver varible in locals the it will be display as "error can not evaluate expression a native frame is on top of the call stack in c#" & thread will stop the execution.
param.update1(rVals1, Convert.ToInt32(dt1["groupID"]));
}
}
}
}
catch { }
finally { }
}
The error you are seeing is not an Exception. The message you see is just letting you know that a native frame is on the top of the stack instead of a managed frame.
It's possible that the error you're seeing has nothing to do with the array - but it's difficult to tell without seeing some of your code.
There are two very common problems involved with multi-threaded programs. If I had to take a guess, you're getting an InvalidOperationException either because the "Object is currently in use" or because "Cross-thread operation not valid".
If the first is the case, you need to use something like:
lock (myObject)
{
// Alter myObject
}
see Locks.
And if the second is the case, you need to use something like:
Invoke(new MethodInvoker(delegate()
{
// Alter stuff in Forms/Controls
}));
see Invoke.
It would really help if you could post the exact Exception you're getting and the code which produces it.
Edit: You have posted a mountain of code to look through. It is very unhelpful.
You say the line causing it is
rvals = _opcServer[serverID1 - 1].Read(array1, Convert.ToInt32(dt1["refreshRate"]));
but nowhere in your code can I see you have declared the variable _opcServer.
As I have already told you, the native frame message isn't an Exception and doesn't mean that there is anything wrong with your program! - it's simply the debugger telling you that it can't give you the values of the managed variables.
Please put this code around the line to identify which type of Exception you are getting, and tell me what the Exception is.
try
{
rvals = _opcServer[serverID1 - 1].Read(array1, Convert.ToInt32(dt1["refreshRate"]));
}
catch (System.Exception ex)
{
System.Windows.Forms.MessageBox.Show("Exception: " + ex.GetType().ToString() +
"\r\nMessage: " + ex.Message);
}