I have the following problem and hope someone can help me.
My basic flow: I want to program any number of devices in parallel using the FTDI D2XX driver and then communicate with them for testing purposes. For this I use two arrays from BackgroundWorker - the first array for programming and the second for testing.
Programming works without any problems. But if I start the BackgroundWorker from the second array to start the test, the connection fails. If I run the complete sequence with only one BackgroundWorker for programming and one BackgroundWorker for testing, the sequence works without problems.
Initialization of BackgroundWorker
private void InitializeBackgoundWorkers()
{
for (var f = 0; f < ftdiDeviceCount; f++)
{
threadArrayProgram[f] = new BackgroundWorker();
threadArrayProgram[f].DoWork += new DoWorkEventHandler(bgr_WorkerStirrerProg_DoWork);
threadArrayProgram[f].RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorkerProgRunWorkerCompleted);
threadArrayProgram[f].WorkerReportsProgress = true;
threadArrayProgram[f].WorkerSupportsCancellation = true;
}
for (var f = 0; f < ftdiDeviceCount; f++)
{
threadArrayTest[f] = new BackgroundWorker();
threadArrayTest[f].DoWork += new DoWorkEventHandler(bgr_WorkerStirrerTest_DoWork);
threadArrayTest[f].RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackgroundWorkerTestRunWorkerCompleted);
threadArrayTest[f].WorkerReportsProgress = true;
threadArrayTest[f].WorkerSupportsCancellation = true;
}
}
Aufruf der BackgroundWorker
private void button2_Click_1(object sender, EventArgs e)
{
if (!bStirrerSerached)
{
vSetProgressBarValueRuehrer(1, imaxprogressbar);
vSearchStirrer();
}
if (FtStatus == FTDI.FT_STATUS.FT_OK)
{
//bgr_Worker_Stirrer.RunWorkerAsync();
InitializeBackgoundWorkers();
//---programmieren---//
for (var f = 0; f < /*FilesToProcess*/ftdiDeviceCount; f++)
{
var fileProcessed = false;
while (!fileProcessed)
{
for (var threadNum = 0; threadNum < MaxThreads; threadNum++)
{
if (!threadArrayProgram[threadNum].IsBusy)
{
Console.WriteLine("Starting Thread: {0}", threadNum);
stemp = "Starting Thread: " + threadNum;
File.AppendAllText(slogfile, stemp);
threadArrayProgram[threadNum].RunWorkerAsync(f);
fileProcessed = true;
Thread.Sleep(1000);
break;
}
}
if (!fileProcessed)
{
Thread.Sleep(50);
}
}
}
//---testen---//
for (var f = 0; f < /*FilesToProcess*/ftdiDeviceCount; f++)
{
var fileProcessed = false;
while (!fileProcessed)
{
for (var threadNum = 0; threadNum < MaxThreads; threadNum++)
{
if (!threadArrayTest[threadNum].IsBusy)
{
Console.WriteLine("Starting Thread: {0}", threadNum);
stemp = "Starting Thread: " + threadNum;
File.AppendAllText(slogfile, stemp);
threadArrayTest[threadNum].RunWorkerAsync(f);
fileProcessed = true;
Thread.Sleep(1000);
break;
}
}
if (!fileProcessed)
{
Thread.Sleep(50);
}
}
}
}
button2.Enabled = false;
}
BackgroundWorker
private void bgr_WorkerStirrerProg_DoWork(object sender, DoWorkEventArgs e)
{
try
{
if (FtStatus == FTDI.FT_STATUS.FT_OK)
{
if (ftdiDeviceList != null)
{
//---db werte sammeln---//
cRuehrerProp = new CRuehrerProperties();
cRuehrerProp.SBenutzer = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
cRuehrerProp.SComputername = System.Windows.Forms.SystemInformation.ComputerName.ToString();
//---Rührer programmieren---//
vStirrerProgram((int)e.Argument);
}
}
}
catch (NotSupportedException /*exc*/)
{
}
finally
{
this.Invoke((MethodInvoker)delegate
{
});
}
}
private void bgr_WorkerStirrerTest_DoWork(object sender, DoWorkEventArgs e)
{
try
{
if (!bfinish)
{
while (!bfinish)
{
if (bfinish)
break;
}
}
//---Test starten---//
vStirrerTest((int)e.Argument);
}
catch (NotSupportedException /*exc*/)
{
}
finally
{
this.Invoke((MethodInvoker)delegate
{
button2.Enabled = true;
myFtdiDevice.Close();
});
}
}
Testing method
private void vStirrerTest(int pos)
{
//threadnr
iPosRuehrerGrid = pos;
Console.WriteLine("Thread {0} StirrerTest", pos);
ftStatus = myFtdiDevice.CyclePort();
UInt32 newFtdiDeviceCount = 0;
do
{
// Wait for device to be re-enumerated
// The device will have the same location since it has not been
// physically unplugged, so we will keep trying to open it until it succeeds
ftStatus = myFtdiDevice.OpenByLocation(ftdiDeviceList[iPosRuehrerGrid].LocId);
Console.WriteLine("try to open locid" + ftdiDeviceList[iPosRuehrerGrid].LocId + " on device " + iPosRuehrerGrid);
//ftStatus = myFtdiDevice.OpenByLocation(ftdiDeviceListOrig[iStirrerPosold[iPosRuehrerGrid]].LocId);
Thread.Sleep(1000);
} while (ftStatus != FTDI.FT_STATUS.FT_OK);
// Close the device
myFtdiDevice.Close();
// Re-create our device list
ftStatus = myFtdiDevice.GetNumberOfDevices(ref newFtdiDeviceCount);
if (ftStatus != FTDI.FT_STATUS.FT_OK)
{
// Wait for a key press
Console.WriteLine("Failed to get number of devices (error " + ftStatus.ToString() + ")");
stemp = "Failed to get number of devices (error " + ftStatus.ToString() + ")";
File.AppendAllText(slogfile, stemp);
return;
}
// Re-populate our device list
ftStatus = myFtdiDevice.GetDeviceList(ftdiDeviceList);
bRepopulateList = true;
vSearchStirrer();
The error occurs in the do loop. If I use only one device - and thus only one thread at a time, it takes an average of 5 runs until the device is opened again. However, if I attach another device and thus have 2 programming and 2 test threads, it does not manage to open the desired device.
I have looked at the DeviceList to make sure it is looking for the right device with the right ID - which it is.
Since I don't have any experience with the Backgrounworker yet, I'm not sure if I haven't forgotten something, which is why this error occurs.