I'm having a threading issue that I'm not sure what to do with.
I'm using Microsoft POS for .NET to initialize some POS hardware. It's horribly slow when used locally and unacceptable on Terminal Services. It takes upwards of 20-40 seconds for three devices. I wanted to multi-thread the initialize of the object on app start up, which was easy. The problem is that one of the objects, the scanner, throws an event when it scans something. The event isn't called from the main thread, since it was created on a
BackgroundWorker
. I never get the call to the event. If it were my event, it'd be easy to marshal it where I needed, but the problem is that it's a hardware vendor's object that I'm using. Any ideas on how to fix this?
I tried putting the actual wire up to the event on the complete sub of the worker but that didn't help. Here's the basic code:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
_scanner.Open();
_scanner.Claim(10000);
_scanner.DeviceEnabled = true;
}
private void OpenScanner()
{
if (_scanner == null)
{
var queryScanner = (from i in _devices.OfType<DeviceInfo>() where i.LogicalNames.Contains(txtScanner.Text) select i).FirstOrDefault();
_scanner = (PosCommon)_posExplorer.CreateInstance(queryScanner);
var bw = new BackgroundWorker();
bw.DoWork += this.bw_DoWork;
bw.RunWorkerCompleted += this.bw_RunWorkerCompleted;
bw.WorkerReportsProgress = false;
bw.WorkerSupportsCancellation = false;
bw.RunWorkerAsync();
}
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
var scan = (Scanner)_scanner;
scan.AutoDisable = false;
scan.DecodeData = true;
scan.DataEventEnabled = true;
scan.DataEvent += this._Scanner_DataEvent;
lblGotScanner.Visible = true;
}
\
MORE INFO for andrew and john,
andrew, the _Scanner_DataEvent is never actually fired. the vendor object never fires off the event(or it's being fired somewhere else on some thread. I don't have any control over that unfortunately or this would be easy to fix.
John,
no it's one object to the scanner at one time. It locks the hardware so another object can't do a .claim on it.
the actual scanner object itself is the vendor's code. To use it, you instantiate it, open it, claim it and then enable it. I instantiate it globally to the app now, and tried wiring up the event before I open/claim it in the UI thread, but it didn't help it. It's like once it's opened.claimed on the background worker, all events are there (or no event is getting fired at all)
one thing i thought of but haven't tried because it complicates it a lot more, is to do the threading myself and keep the other thread open. catch the event there, and then marshal my own event back to my UI thread. Assuming the event is actually getting raised from the scanner, i think this would work.
if i remove the background worker it works fine.