G
Gina_Marano
Hey All,
I am using multiple child threads per main thread to download files.
It sometimes appears as if the same file is being downloaded twice. I
am using "lock". Am I using it correctly? Any blantant threading
errors here?
Any opinions would be greatly appreciated.
namespace MainThreadManagement
{
public delegate string ThreadFinishedCallback();
public class WorkerThread
{
protected string ftpSite;
protected WorkerThread(string aFtpSite)
{
ftpSite = aFtpSite;
}
}
public class MainThread : WorkerThread
{
List<string> arrFileNames = new List<string>();
protected Object GetNextFileLockObj = new Object(); //locking
object
protected Object NotifyThreadFinishedLockObj = new Object(); //
locking object
public MainThread(string aFTPSite): base(aFTPSite)
{
}
public void ProcessFilesToDownload()
{
System.Threading.Thread aThread = null;
ChildThread aChildThread;
ArrayList arrChildThreads = new ArrayList();
string sFileName;
//get a list of the files to download
arrFileNames = GetListOfFiles();
//assume maximum of 10 child threads
for (int i = 0; i < 10; i++)
{
sFileName = GetNextFileName();
if (sFileName == "") //no more
break;
aChildThread = new ChildThread(
new ThreadFinishedCallback(NotifyThreadFinished),
sFileName);
aThread = new System.Threading.Thread(
new ThreadStart(aChildThread.DownloadFile));
arrChildThreads.Add(aThread);
}
//lets get all threads ready then start them.
for (int j = 0; j < arrChildThreads.Count; j++)
{
aThread = (System.Threading.Thread)arrChildThreads[j];
aThread.Start();
}
for (int j = 0; j < arrChildThreads.Count; j++)
{
aThread = (System.Threading.Thread)arrChildThreads[j];
aThread.Join();
}
}
private string GetNextFileName()
{
string sFileName;
lock (GetNextFileLockObj)
{
if (arrFileNames.Count > 0)
{
sFileName = arrFileNames[0];
arrFileNames.RemoveAt(0);
}
return sFileName;
}
}
//called from child threads using callback
private ChilKatFtp.FTPListing NotifyThreadFinished(IsSuccess
aSuccess, string aParent)
{
lock (NotifyThreadFinishedLockObj)
{
string sFileName = "";
sFileName = GetNextFileName();
return sFileName;
}
}
}
}
namespace ChildThreadManagement
{
public class ChildThread : WorkerThread
{
ThreadFinishedCallback NotifyThreadFinished;
string aFileName;
public ChildThread(ThreadFinishedCallback aNotifyThreadFinished,
string aFileName, string aFTPSite)
: base(aFTPSite)
{
NotifyThreadFinished = aNotifyThreadFinished;
sFileName = aFileName;
}
public void DownloadFile()
{
Ftp FtpClient = null;
bool bSuccess;
try {
do {
bSuccess = getFtpConnection(ftpSite, ref FtpClient);
if (bSuccess)
bSuccess = DoDownloadFile(FtpClient, sFileName);
if (bSuccess)
lImageAttribProp = NotifyThreadFinished(lIsSuccess,
lImageAttribProp.sOrderAttribID);
else
sFileName = ""; //causes loop to end
} while (sFileName != ""); }
finally {
if (FtpClient != null)
{
if (FtpClient.IsConnected))
FtpClient.Disconnect();
FtpClient.Dispose();
}
}
}
private bool DoDownloadFile(Ftp FtpClient, string aFileName)
{
//this part works, for simplity of post removed code
return true;
}
private bool getFtpConnection(string aFTPSite, ref Ftp aFtpClient)
{
//this part works, for simplity of post removed code
return true;
}
}
}
I am using multiple child threads per main thread to download files.
It sometimes appears as if the same file is being downloaded twice. I
am using "lock". Am I using it correctly? Any blantant threading
errors here?
Any opinions would be greatly appreciated.
namespace MainThreadManagement
{
public delegate string ThreadFinishedCallback();
public class WorkerThread
{
protected string ftpSite;
protected WorkerThread(string aFtpSite)
{
ftpSite = aFtpSite;
}
}
public class MainThread : WorkerThread
{
List<string> arrFileNames = new List<string>();
protected Object GetNextFileLockObj = new Object(); //locking
object
protected Object NotifyThreadFinishedLockObj = new Object(); //
locking object
public MainThread(string aFTPSite): base(aFTPSite)
{
}
public void ProcessFilesToDownload()
{
System.Threading.Thread aThread = null;
ChildThread aChildThread;
ArrayList arrChildThreads = new ArrayList();
string sFileName;
//get a list of the files to download
arrFileNames = GetListOfFiles();
//assume maximum of 10 child threads
for (int i = 0; i < 10; i++)
{
sFileName = GetNextFileName();
if (sFileName == "") //no more
break;
aChildThread = new ChildThread(
new ThreadFinishedCallback(NotifyThreadFinished),
sFileName);
aThread = new System.Threading.Thread(
new ThreadStart(aChildThread.DownloadFile));
arrChildThreads.Add(aThread);
}
//lets get all threads ready then start them.
for (int j = 0; j < arrChildThreads.Count; j++)
{
aThread = (System.Threading.Thread)arrChildThreads[j];
aThread.Start();
}
for (int j = 0; j < arrChildThreads.Count; j++)
{
aThread = (System.Threading.Thread)arrChildThreads[j];
aThread.Join();
}
}
private string GetNextFileName()
{
string sFileName;
lock (GetNextFileLockObj)
{
if (arrFileNames.Count > 0)
{
sFileName = arrFileNames[0];
arrFileNames.RemoveAt(0);
}
return sFileName;
}
}
//called from child threads using callback
private ChilKatFtp.FTPListing NotifyThreadFinished(IsSuccess
aSuccess, string aParent)
{
lock (NotifyThreadFinishedLockObj)
{
string sFileName = "";
sFileName = GetNextFileName();
return sFileName;
}
}
}
}
namespace ChildThreadManagement
{
public class ChildThread : WorkerThread
{
ThreadFinishedCallback NotifyThreadFinished;
string aFileName;
public ChildThread(ThreadFinishedCallback aNotifyThreadFinished,
string aFileName, string aFTPSite)
: base(aFTPSite)
{
NotifyThreadFinished = aNotifyThreadFinished;
sFileName = aFileName;
}
public void DownloadFile()
{
Ftp FtpClient = null;
bool bSuccess;
try {
do {
bSuccess = getFtpConnection(ftpSite, ref FtpClient);
if (bSuccess)
bSuccess = DoDownloadFile(FtpClient, sFileName);
if (bSuccess)
lImageAttribProp = NotifyThreadFinished(lIsSuccess,
lImageAttribProp.sOrderAttribID);
else
sFileName = ""; //causes loop to end
} while (sFileName != ""); }
finally {
if (FtpClient != null)
{
if (FtpClient.IsConnected))
FtpClient.Disconnect();
FtpClient.Dispose();
}
}
}
private bool DoDownloadFile(Ftp FtpClient, string aFileName)
{
//this part works, for simplity of post removed code
return true;
}
private bool getFtpConnection(string aFTPSite, ref Ftp aFtpClient)
{
//this part works, for simplity of post removed code
return true;
}
}
}