saraff-9EB1047A4BEB4cef8506B29BA325BD5A / Saraff.Twain.NET

Saraff.Twain.NET is the skillful scanning component which allows you to control work of flatbed scanner, web and digital camera and any other TWAIN device from .NET environment. You can use this library in your programs written in any programming languages compatible with .NET technology.
GNU General Public License v3.0
102 stars 35 forks source link

Unable to scan multiple Scanners in Parallel #87

Closed JerinThomas15 closed 2 years ago

JerinThomas15 commented 3 years ago

We have two canon network scanners configured against the machine. For each scan, an instance of Saraff.Twain.Net console application is doing the scanning. We are able to successfully scan in both scanners using the console application. But when we start scanning in parallel only one scanner is scanning, the other scanner is not responding and the console application got stuck.

Can we do scanning in parallel using Saraff Twain.Net.

saraff-9EB1047A4BEB4cef8506B29BA325BD5A commented 3 years ago

Hello, @JerinThomas15 Yes, you can do it. In your case you must using two instance of the Saraff.Twain.Twain32 class in your application. However, there may be additional restrictions on parallel operations imposed by the scanner driver.

JerinThomas15 commented 3 years ago

Hello @saraff-9EB1047A4BEB4cef8506B29BA325BD5A

Yes, we are using two instance of Saraff.Twain.Twain32 class. (By running two console applications Simultaneous) When we are scanning Simultaneous the first scanner is scanning without issues, but the second one is throwing exception while in OpenDataSource.

Exception Saraff.Twain.TwainException: DG DAT MSG out of expected sequence.

Am I missing any configuration for Saraff.Twain.Twain32 class.

saraff-9EB1047A4BEB4cef8506B29BA325BD5A commented 3 years ago

Hello, @JerinThomas15 Likely that the driver of your scanner has restrictions on parallel operations. Try calling to customer service of the scanner manufacturer.

JerinThomas15 commented 3 years ago

@saraff-9EB1047A4BEB4cef8506B29BA325BD5A Currently an another legacy application is running on the machine and that application was able to do parallel scanning without issues.

saraff-9EB1047A4BEB4cef8506B29BA325BD5A commented 3 years ago

@JerinThomas15 In this case make sure that your application (Simultaneous) use same environment (like as 32x|64x platform and 1.x|2.x twain mode) that your the legacy application.

JerinThomas15 commented 3 years ago

@saraff-9EB1047A4BEB4cef8506B29BA325BD5A The legacy application and my application are using the same 32x platform and using 1.x twain mode.

Please find the code we are using for Acquiring Scanned Images.

using Saraff.Twain;
using IoC = Saraff.IoC;

public void AcquireImage(string scannerName)
        {
            var scanners = GetScanners();
            var selectedScanner = scanners.FirstOrDefault(x => x.ScannerName == scannerName);
            var selectedIndex = selectedScanner.ScannerId;
            Twain32 _twain32 = null;
            var scanImagePath = @"C://Scanning//";
            int i = 0;
            try
            {
                var _container = new IoC.ServiceContainer();
                _container.Bind<IStreamProvider, StreamProvider>();
                _twain32 = _container.CreateInstance<Twain32>();               
                _twain32.OpenDSM();
                _twain32.AcquireCompleted += (s, e) =>
                { };
                _twain32.SetupFileXferEvent += (s, e) =>
                {
                    try
                    {
                        e.FileName = $"{scanImagePath}\\{++i}.png";
                    }
                    catch (Exception ex)
                    {  }
                };
                _twain32.AcquireError += (s, e) =>
                {
                    throw e.Exception;
                };
                _twain32.Disposed += (s, e) =>
                {};
                _twain32.EndXfer += (s, e) =>
                {};
                _twain32.FileXferEvent += (s, e) =>
                {};

                _twain32.Language = TwLanguage.ENGLISH_USA;

                _twain32.XferDone += (s, e) =>
                { };
                _twain32.DeviceEvent += (s, e) =>
                {};
                _twain32.SourceIndex = selectedIndex;
                try
                {
                    var status = _twain32.OpenDataSource();              
                    if (!status)
                    {
                        throw new Exception("Scanner Busy. Opening Data source failed");
                    }

                }
                catch (TwainException tEx)
                {
                    // throwing Saraff.Twain.TwainException: DG DAT MSG out of expected sequence.
                    throw tEx;                    
                }
                catch (Exception ex)
                { 
                    throw ex;
                }

                try
                {
                    _twain32.ShowUI = false;
                    _twain32.Capabilities.XferMech.Set(TwSX.File);
                    _twain32.Capabilities.ImageFileFormat.Set(TwFF.Bmp);
                    try
                    {
                        if (_twain32.Capabilities.Duplex.IsSupported(TwQC.GetCurrent))
                        {
                            if ((_twain32.IsCapSupported(TwCap.DuplexEnabled) & TwQC.Set) != 0)
                            {
                                if (_twain32.Capabilities.Duplex.GetCurrent() != TwDX.None)
                                {
                                    _twain32.SetCap(TwCap.DuplexEnabled, true);
                                }
                            }
                        }

                        if ((_twain32.IsCapSupported(TwCap.AutoDiscardBlankPages) & TwQC.Set) != 0)
                        {
                            _twain32.SetCap(TwCap.AutoDiscardBlankPages, TwBP.Auto);

                        }
                        else if ((_twain32.IsCapSupported((TwCap)0x8001) & TwQC.Set) != 0)
                        {
                            _twain32.SetCap((TwCap)0x8001, TwBP.Auto);
                        }

                        _twain32.SetCap(TwCap.Indicators, false);

                    }
                    catch (Exception e)
                    { }

                    _twain32.Acquire();
                }

                catch (TwainException tEx)
                {
                    throw tEx;
                }
                catch (Exception exc)
                {
                    throw exc;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (_twain32 != null)
                {

                    _twain32.CloseDataSource();
                    _twain32.CloseDSM();
                    _twain32.Dispose();
                }
            }
        }

  public List<Scanners> GetScanners()
        {
            var scanners = new List<Scanners>();
            Twain32 _twain32 = new Twain32();
            try
            {
                var status = _twain32.OpenDSM();
                for (int i = 0; i < _twain32.SourcesCount; i++)
                {
                    var scanner = new Scanners()
                    {
                        ScannerId = i,
                        ScannerName = _twain32.GetSourceProductName(i),
                    };

                    scanners.Add(scanner);
                }
            }
            catch (Exception ex)
            {
                throw new Exception("No Scanners Found");
            }
            finally
            {
                _twain32.CloseDSM();
                _twain32.Dispose();
            }

            return scanners;
        }
saraff-9EB1047A4BEB4cef8506B29BA325BD5A commented 3 years ago

Hello, @JerinThomas15 Try using the Saraff.Twain.NET CS Samples and Saraff.Twain.NET Dependency Injection Samples

saraff-9EB1047A4BEB4cef8506B29BA325BD5A commented 3 years ago

@JerinThomas15 I suspect the below line of code does not work correctly in case of two identical scanners

var selectedScanner = scanners.FirstOrDefault(x => x.ScannerName == scannerName);

since it will always return only the first scanner in the list with the specified name

JerinThomas15 commented 3 years ago

@JerinThomas15 I suspect the below line of code does not work correctly in case of two identical scanners

var selectedScanner = scanners.FirstOrDefault(x => x.ScannerName == scannerName);

since it will always return only the first scanner in the list with the specified name

Hello @saraff-9EB1047A4BEB4cef8506B29BA325BD5A The scanners we are using is having two different IPs in their names. So the above code will return the correct scanner based on selection.

Is Calling OpenDSM() twice (for finding the scanners and for scanning) cause this issue.

saraff-9EB1047A4BEB4cef8506B29BA325BD5A commented 3 years ago

Hello, @JerinThomas15

Is Calling OpenDSM() twice (for finding the scanners and for scanning) cause this issue.

Try to cache the list of devices in advance (before starting the scan).

JerinThomas15 commented 3 years ago

Hello, @JerinThomas15

Is Calling OpenDSM() twice (for finding the scanners and for scanning) cause this issue.

Try to cache the list of devices in advance (before starting the scan).

Tried with caching the Devices list. Still having the same error

saraff-9EB1047A4BEB4cef8506B29BA325BD5A commented 2 years ago

Hello, @JerinThomas15 Try using the Saraff.Twain.Sample2 and Saraff.Twain.Sample3 from the Saraff.Twain.NET CS Samples