I am using threads to upload images on a FTP. Now I have a problem in limiting the number of threads. when I am creating same number of threads equal to images then it's fine i.e. it is working fine. But now I want to create only suppose maximum of 5 number of threads to upload 100 or more images. I have a datatable in which these 100 images are with a unique field ID which stores suppose 0,1,2,3....and so on for every images. Now I want to start only five threads once so that it may start uploading 5 images parallely. On a Timer, I am checking the status of threads and if I found a thread which is not live now, I want to assign it the 6th Image for uploading and in the same way, if I found other thread which finished its uploading/work, I want to give it 7th image to upload and so on. i.e. this process will run until 100 images are uploaded.
Can you please suggest me a structure by using which I may achieve this? Currently I am creating 100 threads for 100 images and it is working perfect. But I am afraid of creating that much number of threads. Will that affect performance?
My Current Code is:
// A page level variable
Thread [] tr=null;
//On Load of the Control
tr = new Thread[dt.Rows.Count];
//tr = new Thread[MaxID];
for (int i = 0; i < dt.Rows.Count; i++)
//for (int i = 0; i < MaxID; i++)
{
tr[i] = new Thread(new ThreadStart(ProcessItems));
tr[i].Name = Convert.ToString(dt.Rows[i]["Id"]);
tr[i].IsBackground = true;
}
//Start each thread
foreach (Thread x in tr)
{
x.Start();
}
//The method which is used to upload images
public object tLock = new object();
private void ProcessItems()
{
//if (dict.Count == 0)
// pthread.Suspend();
//ArrayList toRemove = new ArrayList();
lock (tLock)
{
try
{
//int NoofAttempts = 0;
//foreach (DictionaryEntry e in dict)
//{
//Thread.Sleep(500);
dr = dt.Select("Is_Uploaded=0 And Id=" + Thread.CurrentThread.Name).FirstOrDefault();
uxImageAndProgress pbCtl = panelControl1.Controls[dr["Image_ID"].ToString()] as uxImageAndProgress;
//NoofAttempts = 0;
string Path = "";
if (ftpPath == "")
{
Path = Global.FTPRemotePath + "/ProductImages/" + dr["Image_ID"] + dr["Extension"].ToString();
}
else
{
Path = ftpPath + dr["Image_ID"] + dr["Extension"].ToString();
}
//object[] loader = e.Value as object[];
int length = (int)(dr["ActualData"] as byte[]).Length;
Stream stream = new MemoryStream(dr["ActualData"] as byte[]);
byte[] rBuffer = ReadToEnd(stream);
int d = length - (int)stream.Length;
d = Math.Min(d, rnd.Next(10) + 1);
if (ftpRequest == null)
{
try
{
#region New Code
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(Path));
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Credentials = new NetworkCredential(Global.FTPLogIn, Global.FTPPassword);
ftpRequest.UsePassive = true;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = true;
ftpRequest.Timeout = 20000;
ftpRequest.ContentLength = length;
byte[] buffer = new byte[length > 4097 ? 4097 : length];
int bytes = 0;
int total_bytes = (int)length;
System.IO.Stream rs = ftpRequest.GetRequestStream();
while (total_bytes > 0)
{
bytes = stream.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
dr["Is_Uploaded"] = 1;
dt.AcceptChanges();
ftpRequest = null;
pbCtl.Is_Uploaded = true;
rs.Close();
#endregion
}
catch (Exception eeex)
{
ftpRequest = null;
if (ErrorText == "")
ErrorText = eeex.Message.ToString();
else
ErrorText = ErrorText + "," + eeex.Message.ToString();
if (Image_IDsToDelete == "")
Image_IDsToDelete = dr["Image_ID"].ToString();
else
Image_IDsToDelete = Image_IDsToDelete + "," + dr["Image_ID"].ToString();
if (NotUploadedFiles == "")
NotUploadedFiles = Convert.ToString(dr["FileName"]);//dr["Image_ID"] + dr["Extension"].ToString();
else
NotUploadedFiles = NotUploadedFiles + ", " + Convert.ToString(dr["FileName"]);
dr["Is_Uploaded"] = true;
dt.AcceptChanges();
ftpRequest = null;
pbCtl.Is_Uploaded = true;
pbCtl.Is_WithError = true;
}
}
}
catch (Exception ex)
{
XtraMessageBox.Show(ex.Message.ToString(), Global.Header, MessageBoxButtons.OK);
//pthread.Suspend();
}
}
}
//The Timer Event on which I am checking the Status of threads and taking appropriate action
private void timer1_Tick(object sender, EventArgs e)
{
bool Is_AllFinished=true;
//Start each thread
foreach (Thread x in tr)
{
if (x.IsAlive == true)
{
Is_AllFinished = false;
break;
}
else
{
//DataRow[] drs = dt.Select("Is_Uploaded=0");
//if (drs.Count() > 0)
//{
//x. = Convert.ToString(MaxID + 1);
//x.Start();
//MaxID = MaxID + 1;
//}
}
}
if (Is_AllFinished == true)
{
timer1.Enabled = false;
if (Image_IDsToDelete != "")
{
RetailHelper.ExecuteNonQuery("Delete from images where Image_ID in (" + Image_IDsToDelete + ")");
}
if (ErrorText != "")
{
NotUploadedFiles = NotUploadedFiles + ".";
XtraMessageBox.Show("Unable to connect to server. The following files were not uploaded:" + System.Environment.NewLine + NotUploadedFiles + ".", Global.Header, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Is_Done = true;
}
}
Now, I want to convert this code to use a fixed number of threads. Please help me.
Thanking you!
Use a Semaphore it is good enough. You can polish the code yourself.
const int maxThreads = 5;
Semaphore sm = new Semaphore(maxThreads, maxThreads); // maximum concurrent threads
for (int i = 0; i < dt.Rows.Count; i++)
{
try
{
sm.WaitOne();
Thread tr = new Thread(new ThreadStart(ProcessItems));
tr.Name = Convert.ToString(dt.Rows[i]["Id"]);
tr.IsBackground = true;
tr.Start();
}
finally
{
sm.Release();
}
}
// You don't need the timer anymore
// Wait for the semaphore to be completely released
for (int i=0; i<maxThreads ; i++)
sm.WaitOne();
sm.Release(maxThreads);
if (Image_IDsToDelete != "")
{
RetailHelper.ExecuteNonQuery("Delete from images where Image_ID in (" + Image_IDsToDelete + ")");
}
if (ErrorText != "")
{
NotUploadedFiles = NotUploadedFiles + ".";
XtraMessageBox.Show("Unable to connect to server. The following files were not uploaded:" + System.Environment.NewLine + NotUploadedFiles + ".", Global.Header, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
//The method which is used to upload images
private void ProcessItems()
{
//if (dict.Count == 0)
// pthread.Suspend();
//ArrayList toRemove = new ArrayList();
try
{
sm.WaitOne();
try
{
//int NoofAttempts = 0;
//foreach (DictionaryEntry e in dict)
//{
//Thread.Sleep(500);
dr = dt.Select("Is_Uploaded=0 And Id=" + Thread.CurrentThread.Name).FirstOrDefault();
uxImageAndProgress pbCtl = panelControl1.Controls[dr["Image_ID"].ToString()] as uxImageAndProgress;
//NoofAttempts = 0;
string Path = "";
if (ftpPath == "")
{
Path = Global.FTPRemotePath + "/ProductImages/" + dr["Image_ID"] + dr["Extension"].ToString();
}
else
{
Path = ftpPath + dr["Image_ID"] + dr["Extension"].ToString();
}
//object[] loader = e.Value as object[];
int length = (int)(dr["ActualData"] as byte[]).Length;
Stream stream = new MemoryStream(dr["ActualData"] as byte[]);
byte[] rBuffer = ReadToEnd(stream);
int d = length - (int)stream.Length;
d = Math.Min(d, rnd.Next(10) + 1);
if (ftpRequest == null)
{
try
{
#region New Code
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(new Uri(Path));
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpRequest.Credentials = new NetworkCredential(Global.FTPLogIn, Global.FTPPassword);
ftpRequest.UsePassive = true;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = true;
ftpRequest.Timeout = 20000;
ftpRequest.ContentLength = length;
byte[] buffer = new byte[length > 4097 ? 4097 : length];
int bytes = 0;
int total_bytes = (int)length;
System.IO.Stream rs = ftpRequest.GetRequestStream();
while (total_bytes > 0)
{
bytes = stream.Read(buffer, 0, buffer.Length);
rs.Write(buffer, 0, bytes);
total_bytes = total_bytes - bytes;
}
dr["Is_Uploaded"] = 1;
dt.AcceptChanges();
ftpRequest = null;
pbCtl.Is_Uploaded = true;
rs.Close();
#endregion
}
catch (Exception eeex)
{
ftpRequest = null;
if (ErrorText == "")
ErrorText = eeex.Message.ToString();
else
ErrorText = ErrorText + "," + eeex.Message.ToString();
if (Image_IDsToDelete == "")
Image_IDsToDelete = dr["Image_ID"].ToString();
else
Image_IDsToDelete = Image_IDsToDelete + "," + dr["Image_ID"].ToString();
if (NotUploadedFiles == "")
NotUploadedFiles = Convert.ToString(dr["FileName"]);//dr["Image_ID"] + dr["Extension"].ToString();
else
NotUploadedFiles = NotUploadedFiles + ", " + Convert.ToString(dr["FileName"]);
dr["Is_Uploaded"] = true;
dt.AcceptChanges();
ftpRequest = null;
pbCtl.Is_Uploaded = true;
pbCtl.Is_WithError = true;
}
}
}
catch (Exception ex)
{
XtraMessageBox.Show(ex.Message.ToString(), Global.Header, MessageBoxButtons.OK);
//pthread.Suspend();
}
}
finally
{
sm.Release();
}
}
It sounds like a producer / consumer queue is the structure you are looking for. Take a look a this answer and the others in the thread for examples of how to employ it.
Related
I have a windows service,the codes in that body are in a elapsed timer method. I call some web services in a loop,that those web services run in a thread.
I checked the services on servers, they dont start.
And when I take out the codes from thread body,those worked.
This is my windows service code that calls webservices from servers.
private void CallServiceForTrancoding(object sender, System.Timers.ElapsedEventArgs e)
{
DataSet.TranscodingVideosDataTable oTranscodingVideosDataTable = new DataSet.TranscodingVideosDataTable();
DataSetTableAdapters.TranscodingVideoTableAdapter oTranscodingVideoTableAdapter = new DataSetTableAdapters.TranscodingVideoTableAdapter();
oTranscodingVideoTableAdapter.FillVideosForTranscoding(oTranscodingVideosDataTable);
DataSet.ServersDataTable oServersDataTable = new DataSet.ServersDataTable();
DataSetTableAdapters.ServersTableAdapter oServersTableAdapter = new DataSetTableAdapters.ServersTableAdapter();
oServersTableAdapter.FillBaseOnConvertAction(oServersDataTable);
for (int i = 0; i < oTranscodingVideosDataTable.Count; i++)
{
if (oTranscodingVideosDataTable[i].IsQualityNull() == false)
{
var Qualities = oTranscodingVideosDataTable[i].Quality.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
string path = oTranscodingVideosDataTable[i].Path + oTranscodingVideosDataTable[i].ObjectUniqueName;
string[] Url = new string[Qualities.Length];
for (int j = 0; j < Qualities.Length; j++)
{
if (j == 0)
{
Url[j] = path;
}
else
{
Url[j] = path.Replace(path.Split('/').Last(), "") + path.Split('/').Last().Split('.')[0] + "-" + Qualities[j] + "." + path.Split('/').Last().Split('.')[1];
}
}
string parameters = "Token=" + "#HelloWorld" +
"&Url=" + new JavaScriptSerializer().Serialize(Url) +
"&FileUniqueName=" + oTranscodingVideosDataTable[i].ObjectUniqueName +
"&ip=" + oTranscodingVideosDataTable[i].IPValid +
"&GregoreanDate=" + oTranscodingVideosDataTable[i].Gorean_Date.ToString();
DataSet.VideoDataTable oVideoDataTable = new DataSet.VideoDataTable();
DataSetTableAdapters.VideoTableAdapter oVideoTableAdapter = new DataSetTableAdapters.VideoTableAdapter();
oVideoTableAdapter.UpdateVideoStatus(oTranscodingVideosDataTable[i].ObjectUniqueName);
string WebServiceOfServer = oServersDataTable[i].WebService;
WebServiceOfServer = WebServiceOfServer.Replace(WebServiceOfServer.Split('/').Last(), "RS");
JavaScriptSerializer objSerializer = new JavaScriptSerializer();
//Task a = Task.Factory.StartNew(() => {
Task ResponseResult = GetPostMethods.POST(WebServiceOfServer, parameters);
string JSONResult = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(ResponseResult);
var ResponseString = objSerializer.Deserialize<dynamic>(JSONResult);
var UserToken = ResponseString["Result"]["UserToken"];
var Successfully = ResponseString["Result"]["Successfully"];
//});
}
}
}
Here is my web method :
[WebMethod]
public void RS(string Token, string Url, string FileUniqueName, string ip,string GregoreanDate)
{
new Thread(() =>
{
if (Token != "HelloWorld")
{
}
else
{
try
{
var VideoUrl = new JavaScriptSerializer().Deserialize<string[]>(Url);
string[] FileName = new string[VideoUrl.Length];
string[] FilePath = new string[VideoUrl.Length];
t.VideoUniqueName = FileUniqueName.Split('.')[0];
t.mediaOutPath = HttpContext.Current.Server.MapPath("/video/") + DateTime.Parse(GregoreanDate).Year + "\\" + DateTime.Parse(GregoreanDate).Month + "\\" + FileUniqueName.Split('.')[0] + "\\";
t.mediaOutFolderPath = "/video/" + DateTime.Parse(GregoreanDate).Year + "/" + DateTime.Parse(GregoreanDate).Month + "/";
if (!Directory.Exists(t.mediaOutPath))
{
Directory.CreateDirectory(t.mediaOutPath);
Directory.CreateDirectory(t.mediaOutPath + "m3u8\\");
}
t.CreateFTPPathForVideoScheduler(t.VideoTypeFormKey, t.mediaOutPath);
string Paths = "";
for (int i = 0; i < VideoUrl.Length; i++)
{
FileName[i] = VideoUrl[i].Split('/').Last();
if (FileName[i] != FileUniqueName)
{
FilePath[i] = t.mediaOutPath + FileName[i];
}
else
{
FilePath[i] = t.ffmpegFolderPath + FileName[i];
}
using (WebClient client = new WebClientWithAwesomeTimeouts { Timeout = new TimeSpan(10, 0, 0, 0) })
{
try
{
client.DownloadFile(VideoUrl[i], FilePath[i]);
client.Dispose();
}
catch (Exception ex)
{
StreamWriter sw = new StreamWriter(t.LogPath, true);
sw.WriteLine(ex.Message + "----" + ex.StackTrace != null ? ex.StackTrace : "" + "----" + DateTime.Now);
sw.Close();
}
}
}
DirectoryInfo FilesDirectory = new DirectoryInfo(t.ffmpegFolderPath);
FileInfo[] fInfo = FilesDirectory.GetFiles("*" + FileUniqueName.Split('.')[0] + "*.*");
fInfo[0].CopyTo(t.mediaOutPath + FileUniqueName, true);
t.SendFileWithFTPScheduler(t.VideoTypeFormKey, t.mediaOutPath + FileUniqueName);
FilesDirectory = new DirectoryInfo(t.mediaOutPath);
fInfo = FilesDirectory.GetFiles("*" + FileUniqueName.Split('.')[0] + "*.*");
foreach (FileInfo file in fInfo)
{
t.SendFileWithFTPScheduler(t.VideoTypeFormKey, file.FullName);
}
string UniqueFilePath = FilePath[0].Replace(FilePath[0].Split('/').Last(), FileUniqueName);
JavaScriptSerializer objSerializer = new JavaScriptSerializer();
var VideoDimensions = objSerializer.Deserialize<Dictionary<string, string>>(t.getVideoHeightAndWidth(t.ffmpegFolderPath + UniqueFilePath));
string Width = VideoDimensions["Width"];
string Height = VideoDimensions["Height"];
Transcoding.VideoResolutions vr = new Transcoding.VideoResolutions();
var VideoResolutionsInfo = objSerializer.Deserialize<Dictionary<object, object>>(t.getVideoResolution(Height));
vr.OrginalResolution = VideoResolutionsInfo["OrginalResolution"].ToString();
vr.ResCount = Convert.ToInt32(VideoResolutionsInfo["ResCount"]);
vr.OrginalResIndex = Convert.ToInt32(VideoResolutionsInfo["OrginalResIndex"]);
vr.UpperResolutionHeight = VideoResolutionsInfo["UpperResolutionHeight"].ToString();
t.MakeM3U8FormatScheduler(FileUniqueName, vr.OrginalResolution, vr.ResCount, vr.OrginalResIndex, false, "", Height);
t.ProcessFilesScheduler(t.mediaOutPath + "m3u8\\", t.VideoTypeFormKey);
DataSet.VideoDataTable oVideoDataTable = new DataSet.VideoDataTable();
DataSetTableAdapters.VideoTableAdapter oVideoTableAdapter = new DataSetTableAdapters.VideoTableAdapter();
oVideoTableAdapter.UpdateVideoForAcceptation(1, true, "mp4,m3u8", "http://" + t.mediaOutFolderPath + t.VideoUniqueName + "/", FileUniqueName);
oVideoTableAdapter.UpdateStatus("resfinish", FileUniqueName);
foreach (string path in VideoUrl)
{
if (path.ToLower().Contains("mp4videos"))
{
t.FTPDelete(new Uri(path.Replace(new Uri(path).Host, ip).Replace("http", "ftp")));
}
}
System.IO.File.Delete(t.ffmpegFolderPath + UniqueFilePath);
System.IO.Directory.Delete(t.mediaOutPath, true);
}
catch (Exception ex)
{
}
}
}).Start();
}
Task ResponseResult = GetPostMethods.POST(WebServiceOfServer, parameters);
string JSONResult = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(ResponseResult);
You are serializing a task. You surely want to wait for the result, don't you?
I debugged my web service and I found that the issue is related to httpcontext.current in thread is null .
For that I defined HttpContext.Current.Server.MapPath("/video/") as a variable in a class and I recalled it from the webservice.
void BuildProjects()
{
String outputPath = #"D:\PIT\ProcessImprovementTool\DLL";
console = new Process();
console.StartInfo.FileName = "cmd.exe";
console.StartInfo.UseShellExecute = false;
console.StartInfo.CreateNoWindow = true;
console.StartInfo.RedirectStandardInput = true;
console.StartInfo.RedirectStandardOutput = true;
console.StartInfo.RedirectStandardError = true;
console.Exited += new EventHandler((sender, e) =>
{
Console.WriteLine("if (console.Exited) --> ExitCode: " + console.ExitCode);
BuildProjects();
});
console.OutputDataReceived += new DataReceivedEventHandler(ConsoleOutputHandler);
console.ErrorDataReceived += new DataReceivedEventHandler(ConsoleOutputHandler);
console.Start();
using (StreamWriter sw = console.StandardInput)
{
sw.AutoFlush = true;
console.StandardInput.AutoFlush = true;
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("D:\\PIT\\ProcessImprovementTool\\callVcvars32.bat");
sw.WriteLine("cls");
for (int ctr = 0; ctr < 5; ctr++)
{
sw.WriteLine("msbuild /property:OutputPath=" + outputPath + #";OutputType=Library " + lines[ctr]);
//console.BeginOutputReadLine();
sw.Flush();
}
}
if (tryout)
{
Console.WriteLine("working");
}
sw.Close();
//sw.Flush();
}
console.BeginOutputReadLine();
console.BeginErrorReadLine();
//console.WaitForExit();
counter++;
}
in the
for (int ctr = 0; ctr < 5; ctr++)
{
sw.WriteLine("msbuild /property:OutputPath=" + outputPath + #";OutputType=Library " + lines[ctr]);
//console.BeginOutputReadLine();
sw.Flush();
}
if i set the limit for ctr to 40 (ctr < 40) my application hangs, and I get that the stream is already at its limit.
Based on my research, .Flush() should do the trick. or setting AutoFlush to True, but doesn't seem to work.
so how do I clear previous stream records, or anything that would let me input more than 40 lines? (i got 100+ but not more than 150 lines to write in streamWriter).
lines variable stores the value of "build.txt".
void readFromBuild()
{
doneReading = true;
lines = System.IO.File.ReadAllLines(#"D:\PIT\ProcessImprovementTool\Build\build.txt");
//System.Console.WriteLine("Contents of WriteLines2.txt = ");
foreach (string line in lines)
{
lineCount++;
}
Console.WriteLine(lineCount);
lineCount = lineCount - limit;
}
"build.txt" contains all files to be compiled to produce DLL files.
For me, this is as good as answered. I just did it in another way, though it may not be that good.
buildProgress.Enabled = true;
buildProgress.Maximum = lineCount;
for (int ctr = 0; ctr < lineCount; ctr++)
{
String outputPath = #"Q:\";
StreamReader reader;
String outputLine;
console = new Process();
console.StartInfo.FileName = "cmd.exe";
console.StartInfo.UseShellExecute = false;
console.StartInfo.CreateNoWindow = true;
console.StartInfo.RedirectStandardInput = true;
console.StartInfo.RedirectStandardOutput = true;
console.StartInfo.RedirectStandardError = true;
console.Start();
using (StreamWriter sw = console.StandardInput)
{
sw.AutoFlush = true;
console.StandardInput.AutoFlush = true;
if (sw.BaseStream.CanWrite)
{
sw.WriteLine(#"Q:\");
sw.WriteLine("msbuild /property:OutputPath=" + outputPath + #";OutputType=Library " + lines[ctr]);
sw.Flush();
}
sw.Close();
}
reader = console.StandardOutput;
outputLine = reader.ReadToEnd();
console.WaitForExit();
//if (console.HasExited)
//{
Console.Write(outputLine);
//outputTextBox.Text += outputLine;
pathToLog = #"Q:\" + fileList[ctr];
File.Create(pathToLog).Dispose();
File.WriteAllText(pathToLog, outputLine);
buildProgress.Value = ctr;
string[] readThatLog = File.ReadAllLines(pathToLog);
foreach(string line in readThatLog)
{
if (line == "Build succeeded.")
{
outputTextBox.AppendText(lines[ctr]);
outputTextBox.AppendText(Environment.NewLine + line);
outputTextBox.AppendText(Environment.NewLine + Environment.NewLine);
}
else if (line == "Build FAILED.")
{
outputTextBox.AppendText(lines[ctr]);
outputTextBox.AppendText(Environment.NewLine + line);
outputTextBox.AppendText(Environment.NewLine + Environment.NewLine);
}
}
//}
}
buildProgress.Value = 0;
buildProgress.Enabled = false;
Console.WriteLine("\n\n\n\nDONE!!!");
I have a WPF App that allows the user to choose one to many spreadsheets and performs a process to clean the data and write out a pipe delimited files. I am trying to use a Background Worker in order to display a progress bar. The problem I am having is that I have the backgroundworker_DoWork routine to perform the read the excel file, clean the data and write out the data. For each spreadsheet the user is allowed to specify the range for the data or to let Excel decided the range. I call a dialog for this input. I get the error "The calling thread must be STA, because many UI components require this." I have been trying to find a fix for this but everything I try doesn't work.
Here is my code. I have put comments where the offending code is and what I have tried so far.
private void ProcessFiles()
{
int intNumFiles = 0;
string strFileType = "";
int intPos = 0;
string strMsg = "";
intNumFiles = strExFileNames.Length;
foreach (string strInputFile in strExFileNames)
{
intPos = strInputFile.LastIndexOf(".");
strFileType = strInputFile.Substring(intPos + 1);
if(!blnEXTextFileFound)
{
strExcelInputFile = strInputFile;
if (blnExParamCancel || blnMWCancel)
{
strMsg = "Processing has been cancelled.";
System.Windows.MessageBox.Show(strMsg);
break;
}
prgExcelProgress.Visibility = Visibility.Visible;
txtExcelPercent.Visibility = Visibility.Visible;
EnterExcelStateRunning();
try
{
bgwExcelRunner.RunWorkerAsync(strInputFile);
}
catch (Exception ex)
{
System.Windows.MessageBox.Show("Trying to run the Excel/Text file clean process resulted in this error: " + ex.Message, " Error");
prgExcelProgress.Foreground = new SolidColorBrush(Colors.DarkRed);
prgExcelProgress.Value = 100;
}
//ReadWriteExcelData(strInputFile);
}
else
{
if (blnEXTextFileFound)
{
ProcessDelimitedFile(strInputFile);
}
else
{
strMsg = "File type " + strFileType + " is not supported.";
strMsg += " Please contact support.";
System.Windows.MessageBox.Show(strMsg);
}
}
}
prgExcelProgress.Value = 100;
//prgIndicator.Width = 400;
//lblPrctPrgrs.Content = "100%";
//grdProgressIndicator.InvalidateVisual();
//System.Windows.Forms.Application.DoEvents();
//Thread.Sleep(2000);
//txtIndicator.Text = "All files have been processed and created in " + strExOutputPath + ".";
blnDoForAll = false;
}
private void bgwExcelRunner_DoWork(object sender, DoWorkEventArgs e)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range, colrange, rowrange;
string strCellData, strMsg;
string strDataRow = "";
long lngNumRows, lngNumCols = 0;
long intModNumber, lngProgressPct = 0;
double dblProgress = 0;
double dblProgressPct = 0;
string strOutputFileName = "";
int intPos, intProgress = 0;
string strSubFileName = "";
string strFullOutputFileName = "";
string strOutName = "";
long lngColCnt;
string[] strWSNames = new string[0];
Type typCellType;
bool blnMultiWS = false;
string strNumberFormat;
string strFileName = (string)e.Argument;
//string strFileName = (string)((object[])e.Argument)[0];
intPos = strFileName.IndexOf(".");
strSubFileName = strFileName.Substring(0, intPos);
strOutputFileName = strFileName.Substring(strFileName.LastIndexOf("\\") + 1);
strOutName = strOutputFileName.Substring(0, strOutputFileName.IndexOf("."));
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(strFileName, 0, true, 5, "", "", true,
Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
Excel.Sheets excelSheets = xlWorkBook.Worksheets;
if (excelSheets.Count > 1)
{
blnMultiWS = CheckMultipleWorksheets(excelSheets);
if (!blnMultiWS)
{
Array.Clear(strChoosenNames, 0, strChoosenNames.Length);
Array.Resize(ref strChoosenNames, 1);
strChoosenNames[0] = strOutName;
}
}
else
{
Array.Resize(ref strChoosenNames, 1);
strChoosenNames[0] = strOutName;
}
if (blnMWCancel)
{
strMsg = "Processing has been cancelled.";
System.Windows.MessageBox.Show(strMsg);
goto ReadWriteExcelDataExit;
}
foreach (string strCurrWSName in strChoosenNames)
{
//grdProgressIndicator.Visibility = Visibility.Visible;
//txtIndicator.Text = "File: " + strCurrWSName;
//prgIndicator.Width = 0;
//lblPrctPrgrs.Content = "0%";
//System.Windows.Forms.Application.DoEvents();
//txtIndicator.Text = " Processing File: " + strCurrWSName + ". Please wait...";
strFullOutputFileName = strExOutputPath + "\\" + strCurrWSName + "_duc.txt";
//if (strChoosenNames.Length > 1)
//{
// xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets[strCurrWSName];
//}
//else
//{
// xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
//}
try
{
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets[strCurrWSName];
}
catch (Exception exQuery)
{
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
}
if (!blnDoForAll)
{
// I ALSO TRIED TO USE A THREAD. THIS SEEMS TO WORK EXCEPT THAT IT PROCESSING DOESN'T RUN IN THE FOREGROUND SO IT FALLS TO THE CODE AFTER BEFORE THE DIALOG IS DISPLAYED
//Thread thread = new Thread(() =>
//{
// ExcelRowColInfo ercWin = new ExcelRowColInfo(xlWorkSheet.Name);
// ercWin.Left = System.Windows.Application.Current.MainWindow.Left + 15;
// ercWin.Top = System.Windows.Application.Current.MainWindow.Top + 15;
// ercWin.ShowDialog();
// blnExParamCancel = ercWin.blnExCancel;
// strExcelStartCol = ercWin.strStartCol;
// strExcelEndCol = ercWin.strEndCol;
// lngExcelStartRow = ercWin.lngStartRow;
// lngExcelEndRow = ercWin.lngEndRow;
// blnLetExcelDecide = ercWin.blnExcelDecide;
// blnDoForAll = ercWin.blnDoForAll;
//});
//thread.SetApartmentState(ApartmentState.STA);
//thread.IsBackground = false;
//thread.Start();
// THIS IS ONE ATTEMPT TO USE A DISPATCHER, STILL GET THE STA ERROR
//ExcelRowColInfo ercWin = new ExcelRowColInfo(xlWorkSheet.Name);
//ercWin.Left = System.Windows.Application.Current.MainWindow.Left + 15;
//ercWin.Top = System.Windows.Application.Current.MainWindow.Top + 15;
//ercWin.Dispatcher.BeginInvoke
// (
// System.Windows.Threading.DispatcherPriority.Normal,
// (Action)(() =>
// {
// ercWin.ShowDialog();
// blnExParamCancel = ercWin.blnExCancel;
// }
// )
// );
// THIS IS WHERE THE ERROR OCCURS
ExcelRowColInfo ercWin = new ExcelRowColInfo(xlWorkSheet.Name);
ercWin.Left = System.Windows.Application.Current.MainWindow.Left + 15;
ercWin.Top = System.Windows.Application.Current.MainWindow.Top + 15;
ercWin.ShowDialog();
blnExParamCancel = ercWin.blnExCancel;
if (blnExParamCancel)
{
prgExcelProgress.Foreground = new SolidColorBrush(Colors.LightPink);
Dispatcher.BeginInvoke((Action)delegate
{
prgExcelProgress.Value = 100;
txtExcelPercent.Text = "Process has been cancelled";
});
blnExParamCancel = false;
goto ReadWriteExcelDataExit;
}
strExcelStartCol = ercWin.strStartCol;
strExcelEndCol = ercWin.strEndCol;
lngExcelStartRow = ercWin.lngStartRow;
lngExcelEndRow = ercWin.lngEndRow;
blnLetExcelDecide = ercWin.blnExcelDecide;
blnDoForAll = ercWin.blnDoForAll;
if (blnLetExcelDecide)
{
range = xlWorkSheet.UsedRange;
}
else
{
Excel.Range c1 = xlWorkSheet.Cells[lngExcelStartRow, strExcelStartCol];
Excel.Range c2 = xlWorkSheet.Cells[lngExcelEndRow, strExcelEndCol];
range = (Excel.Range)xlWorkSheet.get_Range(c1, c2);
}
colrange = range.Columns;
lngNumCols = colrange.Count;
rowrange = range.Rows;
lngNumRows = rowrange.Count;
if (lngNumRows < 10)
{
intModNumber = lngNumRows;
}
else
{
intModNumber = lngNumRows / 10;
}
if (System.IO.File.Exists(#strFullOutputFileName))
{
System.IO.File.Delete(#strFullOutputFileName);
}
object[,] values = (object[,])range.Value;
long NumRow = 1;
using (StreamWriter file = new StreamWriter(#strFullOutputFileName, true, Encoding.GetEncoding("iso-8859-1")))
{
while (NumRow <= values.GetLength(0))
{
strDataRow = "";
for (lngColCnt = 1; lngColCnt <= lngNumCols; lngColCnt++)
{
if (values[NumRow, lngColCnt] == null)
{
typCellType = typeof(System.String);
}
else
{
typCellType = values[NumRow, lngColCnt].GetType();
}
strCellData = Convert.ToString(values[NumRow, lngColCnt]);
if (typCellType == typeof(System.DateTime))
{
strCellData = strCellData.Substring(0, strCellData.IndexOf(" "));
}
else
{
if (typCellType == typeof(System.Decimal))
{
if (Convert.ToDecimal(values[NumRow, lngColCnt]) == 0)
{
strCellData = Convert.ToString(0);
}
else
{
strCellData = Convert.ToString(values[NumRow, lngColCnt]);
}
}
else
{
if (typCellType != typeof(System.String))
{
strNumberFormat = range[NumRow, lngColCnt].NumberFormat.ToString();
if (strNumberFormat != "General" && strNumberFormat != "Text" && strNumberFormat != "#")
{
if (typCellType == typeof(System.Double))
{
if (strNumberFormat.IndexOf("[Red]") > 0)
{
strCellData = Convert.ToString(range[NumRow, lngColCnt].Value2);
}
else
{
double dblCellValue = double.Parse(strCellData);
strCellData = dblCellValue.ToString(strNumberFormat);
}
}
}
}
}
}
if (strCellData == null)
{
strCellData = string.Empty;
}
else
{
strCellData = strCellData.Replace("\r\n", " ").Replace("\n", " ").Replace("\r", " ");
}
if (lngColCnt == lngNumCols)
{
strDataRow += strCellData;
}
else
{
strDataRow += strCellData + "|";
}
}
file.WriteLine(strDataRow);
if (NumRow % intModNumber == 0)
{
lngProgressPct = (NumRow / lngNumRows);
bgwExcelRunner.ReportProgress((int)lngProgressPct);
}
NumRow++;
}
}
releaseObject(xlWorkSheet);
}
xlWorkBook.Close(false, null, null);
ReadWriteExcelDataExit:
blnMWCancel = false;
xlApp.Quit();
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
Here is the entry point for the ExcelRowColInfo window.
public ExcelRowColInfo(string strWSName)
{
InitializeComponent();
strCurrWSName = string.Copy(strWSName);
InitializeExcelParams();
}
I tried to put [STAThread] above this but get the error "Attributre 'STAThread' is not valid on this declaration type. It is only valid on 'Method' declaration.
How do I do this correctly?
How can I scan (Symantec) a file for a virus while uploading, using Kendo UI Upload?
This question was answered on the Telerik forum:
The Kendo UI Upload does not include any file scanning capabilities
and frankly speaking, we have no intentions with this regard for the
time being. You can scan files via custom implementation or a tool
after saving them on the server, in the same fashion as you would do
that with a plain element.
You'll need to implement general server-side scanning of files, Kendo UI doesn't support it.
using com.symantec.scanengine.api;
public ActionResult Save(IEnumerable<HttpPostedFileBase> files)
{
int bresult = 0;
string sReturn = string.Empty;
bresult = SaveFiles(files);
if (bresult == -2)
{
return Content("Corrupted");
}
else if (bresult == -1)
{
return Content("Incorrect");
}
else
{
return Json("", JsonRequestBehavior.AllowGet);
}
}
public int SaveFiles(IEnumerable<HttpPostedFileBase> files)
{
int bresult = 0;
string sReturn = string.Empty;
if (ModelState.IsValid)
{
string sMessage = null;
try
{
foreach (var file in files)
{
// Some browsers send file names with full path. We only care about the file name.
if ((file != null) && (file.ContentLength > 0) && !string.IsNullOrEmpty(file.FileName))
{
string fileName = System.IO.Path.GetFileName(file.FileName);
string fileExt = System.IO.Path.GetExtension(fileName);
string fileContentType = file.ContentType;
byte[] fileBytes = new byte[file.ContentLength];
bool IsValid = true;
if (IsValid)
{
file.InputStream.Read(fileBytes, 0, Convert.ToInt32(file.ContentLength));
string scanIP = string.Empty;
int scanPort = Convert.ToInt16(ConfigurationManager.AppSettings["scanPort"]);
scanIP = ConfigurationManager.AppSettings["scanIPFromConfig"];
int scanResult = ScanUploads(scanIP, scanPort, fileName, fileBytes);
if (scanResult == -1)
{
bresult = -2;
}
else
{
//your logic to remove files
}
}
}
}
}
catch (Exception ex)
{
ModelState.AddModelError("", ex.Message.ToString());
obj.ExceptionLogger(ex);
bresult = -1;
}
}
return bresult;
}
public int ScanUploads(string ScanIP, int scanPort, string valuetoscan, byte[] fileStream)
{
//try
//{
List<ScanEngineInfo> scanEnginesForScanning = new List<ScanEngineInfo>();
scanEnginesForScanning.Add(new ScanEngineInfo(ScanIP, scanPort));
//ScanEngineInfo scanEnginesForScanning = new ScanEngineInfo(ScanIP, scanPort);
ScanRequestManager requestManagerObj = new ScanRequestManager();
requestManagerObj.PrepareForScan(scanEnginesForScanning, 20000, 20);
//string scanPolicy = "policy";
string setScanPolicy = "DEFAULT";
dynamic scPolicy = (Policy)Enum.Parse(typeof(Policy), setScanPolicy);
StreamScanRequest testobjtoscan = requestManagerObj.CreateStreamScanRequest(scPolicy);
// byte[] array1 = null;
// int i = 0;
MemoryStream iStream = new MemoryStream();
ScanResult scanResult = default(ScanResult);
string scanresultClean = null;
int scanresultINFECTED = 0;
string scanresultcount = null;
string scanfilestatus = null;
iStream.Write(fileStream, 0, fileStream.Length);
testobjtoscan.Start(valuetoscan, "ScanFile");
testobjtoscan.Send(fileStream);
try
{
scanResult = testobjtoscan.Finish(iStream);
}
catch (Exception e)
{
throw;
}
scanfilestatus = Convert.ToString(scanResult.fileStatus.ToString());
scanresultcount = scanResult.threat.ToString();
scanresultClean = scanResult.fileStatus.ToString();
scanresultINFECTED = scanResult.totalInfection;
if (scanfilestatus != "CLEAN")
{
string errorMessage;
if(scanfilestatus == null)
{
errorMessage = "File Scan Status: null" + " Total Infection: " + scanResult.totalInfection + " connTriesInfo: ";
}
else{
errorMessage = "File Scan Status: " + scanfilestatus + " Total Infection: " + scanResult.totalInfection + " connTriesInfo: ";
}
foreach (var conninfo in scanResult.connTriesInfo)
{
errorMessage += " port: " + conninfo.port.ToString() + " problem encountered:" + conninfo.problemEncountered.ToString() + " scan host" + conninfo.scanHost.ToString();
}
iStream.Dispose();
Exception ex = new Exception("Symantec Virus Scan prevented file from being uploaded " + errorMessage);
obj.ExceptionLogger(ex);
return -1;
}
else
return 0;
}
public int ScanStream(string scanServer, int scanPort, string fileName, byte[] fileStream)
{
byte[] buffer = new byte[1024];
int iRx;
Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string retDesc=string.Empty;
try
{
if (scanPort == 0)
scanPort = 1344;
System.Net.IPAddress remoteIPAddress = System.Net.IPAddress.Parse(scanServer);
System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(remoteIPAddress, scanPort);
soc.Connect(remoteEndPoint);
if (soc.Connected)
{
string cmd = "RESPMOD icap://" + scanServer + ":" + scanPort + "/AVSCAN ICAP/1.0\n";
cmd = cmd + "Host: " + scanServer + ":" + scanPort + "\n";
cmd = cmd + "Allow: 204\n";
cmd = cmd + "Encapsulated: req-hdr=0, res-hdr=84, res-body=131\n";
cmd = cmd + "\n";
cmd = cmd + "GET http://”" + scanServer + "/" + fileName + " HTTP/1.1\n";
cmd = cmd + "Host: " + scanServer + "\n";
cmd = cmd + "\n";
cmd = cmd + "HTTP/1.1 200 OK\n";
cmd = cmd + "Transfer-Encoding: chunked\n";
cmd = cmd + "\n";
cmd = cmd + String.Format("{0:X2}", fileStream.Length) + "\n";
soc.Send(System.Text.Encoding.ASCII.GetBytes(cmd));
soc.Send(fileStream);
cmd = "\n";
cmd = cmd + "\n";
cmd = cmd + "0\n";
cmd = cmd + "\n";
soc.Send(System.Text.Encoding.ASCII.GetBytes(cmd));
while ((soc.Connected) && ((iRx = soc.Receive(buffer)) > 0))
{
char[] chars = new char[iRx];
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(buffer, 0, iRx, chars, 0);
System.String szData = new System.String(chars);
retDesc = retDesc + szData;
}
soc.Close();
if (retDesc.Contains("X-Violations-Found:"))
return -1;
else
return 0;
}
else
return -1;
}
catch (Exception e)
{
if (soc != null)
soc.Close();
retDesc = e.Message;
obj.ExceptionLogger(e);
return -1;
}
}
I'm creating a tool that reads information from a file and also displays an image extracted from said file as well. it reads the info just fine and everything but when it comes to displaying the image it freezes the program without an error. the program just becomes unresponsive. the debugger doesn't say anything either except after some time it will say the thread has exited with still no response from the program.
i need to rename some stuff as i don't want to get in trouble
Here's the code I'm using to extract and display the image:
try
{
global.meta.filetype = STFSRead.readString_C(0, 4);
textBox2.Text = global.meta.filetype;
textBox3.Text = STFSRead.detectType(global.meta.contype.ToString("X4"));
textBox4.Text = global.meta.metaversion.ToString();
textBox5.Text = global.meta.id1;
textBox6.Text = global.meta.version.ToString("X");
textBox7.Text = global.meta.version2.ToString("X");
textBox8.Text = global.meta.id2;
textBox9.Text = global.meta.id3;
textBox10.Text = global.meta.id4;
textBox11.Text = global.meta.id5;
textBox12.Text = global.meta.displayname;
textBox13.Text = global.meta.titlename;
textBox14.Text = STFSRead.detectSomeInfo(global.meta.aflag.ToString("X2"));
pictureBox1.Image = STFSRead.loadImage();
}
catch
{
throw new Exception("What did you do?\n All this is suppose to do is read a file, how did you screw that up?");
}
public static Image loadImage()
{
Exception failed = new Exception("LoadImage failed. Contact a developer");
string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/appname/cache/";
string imgname = global.meta.id.Replace(" ", "") + ".png";
if (Directory.Exists(#path))
{
if (File.Exists(#path + imgname))
{
using (Image img = Image.FromFile(#path + imgname))
{
return img;
}
throw failed;
}
else if (!File.Exists(#path + imgname))
{
if (extractData(imgname, 0x171A, 0x4000))
{
using (Image img = Image.FromFile(#path + imgname))
{
return img;
}
throw failed;
}
else
throw failed;
}
else
throw failed;
}
else if(!Directory.Exists(#path)){
Directory.CreateDirectory(#path);
if (File.Exists(#path + imgname))
{
using (Image img = Image.FromFile(#path + imgname))
{
return img;
}
throw failed;
}
else if (!File.Exists(#path+imgname))
{
if (extractData(imgname, 0x171A, 0x4000))
{
using (Image img = Image.FromFile(#path + imgname))
{
return img;
}
throw failed;
}
else
throw failed;
}
else
throw failed;
}
else
throw failed;
}
public static bool extractData(string filename, long startpos, long length)
{
string data = STFSRead.readString_A(startpos, length);
string path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)+"/appname/cache/";
if (Directory.Exists(#path))
{
using (StreamWriter file = new StreamWriter(#path + filename))
{
file.Write(data);
file.Close();
}
}
else if (!Directory.Exists(#path))
{
Directory.CreateDirectory(#path);
using (StreamWriter file = new StreamWriter(#path + filename))
{
file.Write(data);
file.Close();
}
}
if (File.Exists(#path + filename))
return true;
else
throw new Exception("Couldn't extract file "+filename+" at location "+startpos+" with a length of "+length);
}
public static string readString_A(long startpos, long length)
{
string s = "";
for (long i = startpos; i < startpos + length; i = i++)
{
global.fs.Position = i;
byte[] buf = new byte[1];
global.fs.Read(buf, 0, 1);
if (buf[0] == 0x00) // Null symbol
{
}
else
{
char c = Convert.ToChar(buf[0]);
s += c;
}
}
if (s == "" || s == " ")
{
s = "";
}
return s;
}
I have checked my appdata folder and while the directory gets created, the image does not get created so i'm thinking its failing during extraction. and none of my exceptions get triggered either
Edit: about the exceptions.... i added all of them when the program started screwing up to see if it will trigger them and narrow down where the error might be. i don't want it to handle those exceptions. might not be the best way to do that but i am still learning c# so i don't expect it to be the best way. if there is a better way to do this then let me know.
I think your problem is here:
for (long i = startpos; i < startpos + length; i = i++)
It should be:
for (long i = startpos; i < startpos + length; i++)
i=i++ is not actually incremeting the variable
You can find why here: i = i++ doesn't increment i. Why?. Thanks to #RenniePet for the link.