MyThread.Join() blocks the whole application. Why? - c#

I want to download a file from a FTP server in the other Thread. The problem is, this thread causes that my application is freezed. Here You have the code, what am I doing wrong? Any help will by grateful :)
(Of course I want to stop looping until the thread 'ReadBytesThread' terminates.)
I make a new thread:
DownloadThread = new Thread(new ThreadStart(DownloadFiles));
DownloadThread.Start();
private void DownloadFiles()
{
if (DownloadListView.InvokeRequired)
{
MyDownloadDeleg = new DownloadDelegate(Download);
DownloadListView.Invoke(MyDownloadDeleg);
}
}
private void Download()
{
foreach (DownloadingFile df in DownloadingFileList)
{
if (df.Size != "<DIR>") //don't download a directory
{
ReadBytesThread = new Thread(() => {
FileData = sendPassiveFTPcmd("RETR " + df.Path + "/" + df.Name + "\r\n");
FileStream fs = new FileStream(#"C:\Downloads\" + df.Name, FileMode.Append);
fs.Write(FileData, 0, FileData.Length);
fs.Close();
});
ReadBytesThread.Start();
(here->) ReadBytesThread.Join();
MessageBox.Show("Downloaded");
}
}
}

you're calling DownloadFiles in a secondary thread but this function call Download() in the UI thread via DownloadListView.Invoke --> your application freezes because the download is done in the main thread.
you can try this approach:
DownloadThread = new Thread(new ThreadStart(DownloadFiles));
DownloadThread.Start();
private void DownloadFiles()
{
foreach (DownloadingFile df in DownloadingFileList)
{
if (df.Size != "<DIR>") //don't download a directory
{
ReadBytesThread = new Thread(() => {
FileData = sendPassiveFTPcmd("RETR " + df.Path + "/" + df.Name + "\r\n");
FileStream fs = new FileStream(#"C:\Downloads\" + df.Name,
FileMode.Append);
fs.Write(FileData, 0, FileData.Length);
fs.Close();
});
ReadBytesThread.Start();
ReadBytesThread.Join();
if (DownloadListView.InvokeRequired)
{
DownloadListView.Invoke(new MethodInvoker(delegate(){
MessageBox.Show("Downloaded");
}));
}
}
}
}

Related

Parallel for each loop does not save all files

I writing on an image converter. When I use parallel for each not all images are saved. Is the processing too fast for writing files on disk?
Here is my code:
private void convert()
{
Parallel.ForEach(source.GetFiles("*.tif"),
new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
file =>
{
fileName = file.Name;
MagickImage image = new MagickImage(sourceFolderPath + "\\" + file);
image.ColorSpace = ColorSpace.XYZ;
image.GammaCorrect(2.4);
image.Write(destinationFolderPath + "\\" + fileName);
});
}
What did I do wrong?
Try disposing the image:
private void convert()
{
Parallel.ForEach(source.GetFiles("*.tif"),
new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
file =>
{
fileName = file.Name;
using (MagickImage image = new MagickImage(sourceFolderPath + "\\" + file))
{
image.ColorSpace = ColorSpace.XYZ;
image.GammaCorrect(2.4);
image.Write(destinationFolderPath + "\\" + fileName);
}
});
}

C# console application stops after nearly 8 minutes

I have a C# console application which reads a folder for every 15 seconds using timer. It works fine,but it pauses after nearly 8 minutes and stops reading folder. Is there any reason for that?
using System;
sing System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Data;
using System.Data.OracleClient;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace FolderFileReader
{
class Program
{
static void Main()
{
if (SingleInstance.SingleApplication.Run() == false)
{
return;
}
Thread thread1 = new Thread(new ThreadStart(startNewBusiness));
thread1.Start();
Thread thread2 = new Thread(new ThreadStart(startEndorsement));
thread2.Start();
Thread thread3 = new Thread(new ThreadStart(startRenewal));
thread3.Start();
Thread thread4 = new Thread(new ThreadStart(startCancellation));
thread4.Start();
Console.ReadLine();
}
private static void startNewBusiness()
{
Timer t = new Timer(ProcessNewBusinessFolder, null, 0, 5000);
}
private static void startEndorsement()
{
Timer t2 = new Timer(ProcessEndorsementFolder, null, 0, 5000);
}
private static void startRenewal()
{
Timer t3 = new Timer(ProcessRenewalFolder, null, 0, 5000);
}
private static void startCancellation()
{
Timer t4 = new Timer(ProcessCancellationFolder, null, 0, 5000);
}
private static void ProcessNewBusinessFolder(Object o)
{
Console.Clear();
Console.WriteLine("Do not close this console (New Business).... ");
DirectoryInfo d = new DirectoryInfo(#"E:\HNBGI\SCN_DOCS\NEW\");
DirectoryInfo dest = new DirectoryInfo(#"E:\HNBGI\QUEUED_SCN_DOCS\NEW\");
if (!d.Exists)
{
return;
}
FileInfo[] Files = d.GetFiles("*.pdf");
string quotationNo = "";
string branchCode = "";
foreach (FileInfo file in Files)
{
quotationNo = file.Name;
DirectoryInfo newDir = null;
if (!Directory.Exists(dest.FullName + quotationNo.ToUpper()))
{
// newDir = Directory.CreateDirectory(dest.FullName + quotationNo.ToUpper() + "\\");
System.IO.Directory.CreateDirectory(dest.FullName + quotationNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper());
}
if (quotationNo.Length > 10)
{
branchCode = quotationNo.Substring(2, 3);
}
Console.WriteLine(quotationNo + " - " + branchCode);
try
{
File.Move(file.FullName, dest.FullName + quotationNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper() + "\\" + file.Name.ToUpper());
InsertNewBusiness(quotationNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper(), branchCode, "N");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Console.ReadKey();
GC.Collect();
}
private static void ProcessEndorsementFolder(Object o)
{
Console.Clear();
Console.WriteLine("Do not close this console (Endorsement).... ");
DirectoryInfo d = new DirectoryInfo(#"E:\HNBGI\SCN_DOCS\ENDORSEMENT\");
DirectoryInfo dest = new DirectoryInfo(#"E:\HNBGI\QUEUED_SCN_DOCS\ENDORSEMENT\");
if (!d.Exists)
{
return;
}
FileInfo[] Files = d.GetFiles("*.pdf");
string jobNo = "";
string branchCode = "";
foreach (FileInfo file in Files)
{
jobNo = file.Name;
DirectoryInfo newDir = null;
if (!Directory.Exists(dest.FullName + jobNo.ToUpper()))
{
System.IO.Directory.CreateDirectory(dest.FullName + jobNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper());
}
Console.WriteLine(jobNo + " - " + branchCode);
try
{
File.Move(file.FullName, dest.FullName + jobNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper() + "\\" + file.Name.ToUpper());
UpdateEndorsement(jobNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Console.ReadKey();
// Force a garbage collection to occur for this demo.
GC.Collect();
}
private static void ProcessRenewalFolder(Object o)
{
Console.Clear();
Console.WriteLine("Do not close this console (Renewal).... ");
DirectoryInfo d = new DirectoryInfo(#"E:\HNBGI\SCN_DOCS\RENEWAL\");
DirectoryInfo dest = new DirectoryInfo(#"E:\HNBGI\QUEUED_SCN_DOCS\RENEWAL\");
if (!d.Exists)
{
return;
}
FileInfo[] Files = d.GetFiles("*.pdf");
string jobNo = "";
string branchCode = "";
foreach (FileInfo file in Files)
{
jobNo = file.Name;
DirectoryInfo newDir = null;
if (!Directory.Exists(dest.FullName + jobNo.ToUpper()))
{
System.IO.Directory.CreateDirectory(dest.FullName + jobNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper());
}
Console.WriteLine(jobNo + " - " + branchCode);
try
{
File.Move(file.FullName, dest.FullName + jobNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper() + "\\" + file.Name.ToUpper());
UpdateRenewal(jobNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Console.ReadKey();
// Force a garbage collection to occur for this demo.
GC.Collect();
}
private static void ProcessCancellationFolder(Object o)
{
Console.Clear();
Console.WriteLine("Do not close this console (Cancellation).... ");
DirectoryInfo d = new DirectoryInfo(#"E:\HNBGI\SCN_DOCS\CANCELLATION\");
DirectoryInfo dest = new DirectoryInfo(#"E:\HNBGI\QUEUED_SCN_DOCS\CANCELLATION\");
if (!d.Exists)
{
return;
}
FileInfo[] Files = d.GetFiles("*.pdf");
string jobNo = "";
string branchCode = "";
foreach (FileInfo file in Files)
{
jobNo = file.Name;
DirectoryInfo newDir = null;
if (!Directory.Exists(dest.FullName + jobNo.ToUpper()))
{
// newDir = Directory.CreateDirectory(dest.FullName + quotationNo.ToUpper() + "\\");
System.IO.Directory.CreateDirectory(dest.FullName + jobNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper());
}
string outputFileWithPath = "";
outputFileWithPath = dest.FullName + jobNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper() + "\\" + file.Name.ToUpper();
Console.WriteLine(jobNo + " - " + branchCode);
try
{
File.Move(file.FullName, outputFileWithPath);
UpdateCancellation(jobNo.Substring(0, file.Name.LastIndexOf(".")).ToUpper());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Console.ReadKey();
GC.Collect();
}
public static void InsertNewBusiness(string quotationNo, string branchCode, string JobType)
{
\\Code to put Database Entry
}
public static void UpdateEndorsement(string jobNo)
{
\\Code to put Database Entry
}
public static void UpdateRenewal(string jobNo)
{
\\Code to put Database Entry
}
public static void UpdateCancellation(string jobNo)
{
\\Code to put Database Entry
}
}
}
Can anyone guess the issue?
Seems timers are collected by GC. Try to declare timers in outer scope.
private static Timer t;
private static Timer t2;
...and so on.

Append text in exclusively opened file

I am trying to implement locking scenario where same file is accessed by multiple threads at same time or at different time. While testing it seems code is overwriting the existing line instead of appending new line.
namespace SMPPService
{
public static class LogFile
{
public static void WriteErrorLog(Exception ex)
{
byte[] buf = GetBytes(DateTime.Now.ToString() + ": " + ex.Source.ToString().Trim() + "; " + ex.Message.ToString().Trim());
Lock(HttpRuntime.AppDomainAppPath + "\\Exceptions.txt",
(f) =>
{
try
{
f.Write(buf, 0, buf.Length);
}
catch (IOException ioe)
{
// handle IOException
}
}, buf);
}
public static void WriteErrorLog(string Message)
{
byte[] buf = GetBytes(DateTime.Now.ToString() + ": " + Message);
Lock(HttpRuntime.AppDomainAppPath + "\\LogFile.txt",
(f) =>
{
try
{
f.Write(buf, 0, buf.Length);
}
catch (IOException ioe)
{
// handle IOException
}
}, buf);
System.Threading.Thread.Sleep(60000);
}
public static void Lock(string path, Action<FileStream> action,byte [] lines)
{
var autoResetEvent = new AutoResetEvent(false);
while (true)
{
try
{
using (var file = File.Open(path,
FileMode.OpenOrCreate,
FileAccess.ReadWrite,
FileShare.Write))
{
action(file);
break;
}
}
catch (IOException)
{
var fileSystemWatcher =
new FileSystemWatcher(Path.GetDirectoryName(path))
{
EnableRaisingEvents = true
};
fileSystemWatcher.Changed +=
(o, e) =>
{
if (Path.GetFullPath(e.FullPath) == Path.GetFullPath(path))
{
autoResetEvent.Set();
}
};
autoResetEvent.WaitOne();
}
}
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
}
}
Usage
LogFile.WriteErrorLog("Requesting SMPP Client from WMAS..." + " " + "Date:" + DateTime.Now + " " + "Source Address:" + msisdn);
FileShare.Write
From MSDN:
Allows subsequent opening of the file for writing.
This is exactly the flag you do not want to use. With files the easiest way to do locking is to let the file system do it for you, use FileShare.Read (so someone can look at the log) and retry if the open fails do to a sharing violation.
Implementing your own locking like that is only going to be re-creating when the file system already does, but badly.
Also, rather than messing handling encoding yourself (getting the edge cases right is not easy):
Open as a text file with a specified encoding (UTF-8 would be my choice).
Open the file for append, so new content will always be written at the end.
There is an overload of StreanWriter's constructor that does this.
EDIT: A quick check of the reference source: this does use FileShare.Read.
You should use File.AppendAllLines instead your lock method. File.AppendAllLines is not Thread safe and you have to lock it.
private object lockObject = new object();
private string fileName = Path.Combine(HttpRuntime.AppDomainAppPath, "LogFile.txt");
public static void WriteErrorLog(string Message)
{
lock(lockObject)
{
File.AppendAllLines(fileName, new string[] { Message + "\n" });
}
}
note that File.AppendAllLines was introduced in .Net 4 and you have to use File.AppendAllText in older framework

Error while fetching record using thread in c#

I am trying to run the thread to fetch the result simultaneously from the network on the basis of the query. Below is my code for thread calling
for(int i=0;i<numberOfConnection;i++)
{
//threadResult[i] = onListen(s[i], toquery);
exec[i] = new Thread(() => threadResult[i] = onListen(s[i], toquery));
exec[i].Start();
}
and onListen function is
private string onListen(Socket s,string query)
{
string returnmsg = DateTime.Now.ToString("HH:mm:ss.ffff tt"); //= Start Time ===
try
{
Stream ss = new NetworkStream(s);
StreamReader sr = new StreamReader(ss);
StreamWriter sw = new StreamWriter(ss);
sw.AutoFlush = true;
sw.WriteLine(query);
returnmsg += " " + sr.ReadLine() + " " + DateTime.Now.ToString("HH:mm:ss.ffff tt"); //== End Time ==
s.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return returnmsg;
}
But I am getting error of index out of range exception.
If I run the same code without using thread like this
threadResult[i] = onListen(s[i], toquery);
it works. Kindly help me tracking the bug.
Try this:
for(int i=0;i<numberOfConnection - 1;i++)
{
//threadResult[i] = onListen(s[i], toquery);
exec[i] = new Thread(() => threadResult[i] = onListen(s[i], toquery));
exec[i].Start();
}
Or
for(int i=1;i<numberOfConnection;i++)
{
//threadResult[i] = onListen(s[i], toquery);
exec[i] = new Thread(() => threadResult[i] = onListen(s[i], toquery));
exec[i].Start();
}

Disposing File Object Properly

Ok so heres the thing. When ever a trigger is hit i append my logs in a specific folder. The code works fine and it appends it correctly but if i try to manually delete the folder from the desktop its giving a "The action cannot be completed cause the folder/file is open in another program";
i guess im not disposing it right but i dont know where i missed it. I know its the folder that is attached to the process cause i tried to delete the .log file inside and it allowed me.
private void LogEvent(string filename,bool AppendTxt,string msg)
{
string sLogFormat = DateTime.Now.ToShortDateString().ToString() + " " + DateTime.Now.ToLongTimeString().ToString() + " ==> ";
msg = sLogFormat + msg;
// create directory
if (System.IO.Directory.Exists("C:\\Users\\DT-Npax\\Desktop\\LOGS1") != true)
{
Directory.CreateDirectory("C:\\Users\\DT-Npax\\Desktop\\LOGS1");
}
string dailyLog = "C:\\Users\\DT-Npax\\Desktop\\LOGS1" + "\\" + filename + ".log";
FileStream FS = null;
//write or append txt
if (!AppendTxt)
{
if (File.Exists(dailyLog))
{
File.Delete(dailyLog);
}
using (FS = File.Create(dailyLog)) { }
FS.Close();
StreamWriter TXT_WRITE = new StreamWriter(dailyLog);
TXT_WRITE.WriteLine(msg);
TXT_WRITE.Close();
}
else
{
if (!File.Exists(dailyLog))
{
using (FS = File.Create(dailyLog)) { }
FS.Close();
}
FileStream FSAppend = new FileStream(dailyLog, FileMode.Append, FileAccess.Write);
StreamWriter TXT_WRITE = new StreamWriter(FSAppend);
TXT_WRITE.WriteLine(msg);
TXT_WRITE.Close();
FSAppend.Close();
}
}
Your code does seem to close the file properly but not in an exception-safe manner.
You also have some unnecessary code in there (like using (FS = File.Create(dailyLog)) { } FS.Close(); ).
The smallest modification looks like this:
else
{
//if (!File.Exists(dailyLog))
//{
// using (FS = File.Create(dailyLog)) { }
// FS.Close();
//}
using (FileStream FSAppend = new FileStream(dailyLog, FileMode.Append, FileAccess.Write))
using (StreamWriter TXT_WRITE = new StreamWriter(FSAppend))
{
TXT_WRITE.WriteLine(msg);
}
//TXT_WRITE.Close();
//FSAppend.Close();
}
But I would rewrite this whole method like:
private void LogEvent(string filename,bool AppendTxt,string msg)
{
string sLogFormat = DateTime.Now.ToShortDateString().ToString() + " "
+ DateTime.Now.ToLongTimeString().ToString() + " ==> ";
msg = sLogFormat + msg;
// create directory
if (System.IO.Directory.Exists("C:\\Users\\DT-Npax\\Desktop\\LOGS1") != true)
{
Directory.CreateDirectory("C:\\Users\\DT-Npax\\Desktop\\LOGS1");
}
string dailyLog = "C:\\Users\\DT-Npax\\Desktop\\LOGS1" + "\\" + filename + ".log";
if (AppendText)
System.IO.File.AppendAllText(dailylog, msg);
else
System.IO.File.WriteAllText(dailylog, msg);
}
There is no need to pre-create or delete files.
Wrap the streams in a using block since they implement IDisposable.
I must say this code is a little odd...
using (FS = File.Create(dailyLog)) { }
FS.Close();
StreamWriter TXT_WRITE = new StreamWriter(dailyLog);
TXT_WRITE.WriteLine(msg);
TXT_WRITE.Close();
Shouldn't it be something like:
using (FileStream FS = File.Create(dailyLog))
{
using(StreamWriter TXT_WRITE = new StreamWriter(dailyLog))
{
TXT_WRITE.WriteLine(msg);
}
}

Categories

Resources