- marked as enhancement
Is there a way to scan synhronously? Or await asynchronously?
Is there simple way to scan synchronously, and then continue work with scanned images? Or some Task to asynchronously await, with images as result?
I just come with not so convenient solution:
var done = new ManualResetEvent(false);
twain.SourceDisabled += (s, e) => done.Set();
...
while (!done.WaitOne(100)) Thread.Sleep(100);
Is there better way?
Comments (8)
-
reporter -
reporter Sorry. For some unknown reason I was thinking that the DataSource.Enable method was asynchronous. Maybe message loop confused me. Scanning is already synchronous, right?
-
repo owner TWAIN scanning is always async (non-blocking method call); i.e. Enable() returns before actual scanning happens where the paper/camera moves and then you get an event with the scanned data.
Perhaps you are confusing sync/async with the UI blocking where window can't be moved during scanning. Those could be due to different reasons.
-
reporter In another issue you told that I can check for Cancel returning from the Enable method. So part of this method will be sync? It blocks until user choose settings in WIA wizard?
-
repo owner Yes that's a WIA thing. Real TWAIN settings dialog is async, and physical scanning time is also async.
-
reporter Wia and Twain work different. I get it, thank you. So is there a way to make method which will take scanner name as input and return images as output without using things like ManualResetEvent and Thread.Sleep? Or what is the default pattern to scan all papers and then continue to work with acquired images?
-
repo owner You can create a wrapper that does all the waiting hard work, like this example using task (this is a quick write-up and not guaranteed to work).
class ScanTaskWrapper { TwainSession _session; TaskCompletionSource<List<string>> _tcs; List<string> _imageFiles; public ScanTaskWrapper() { _session = new TwainSession(DataGroups.Control | DataGroups.Image); _session.SourceDisabled += _session_SourceDisabled; _session.DataTransferred += _session_DataTransferred; } public Task<List<string>> ScanImages(string scanner) { // will have to check for return codes on all calls _session.Open(); var source = _session.FirstOrDefault(device => device.Name == scanner); source.Open(); _tcs = new TaskCompletionSource<List<string>>(); _imageFiles = new List<string>(); if (source.Enable(SourceEnableMode.ShowUI, false, IntPtr.Zero) != ReturnCode.Success) { _tcs.SetResult(_imageFiles); } return _tcs.Task; } private void _session_DataTransferred(object sender, DataTransferredEventArgs e) { var savedFile = ""; // maybe save data to file and add to image list _imageFiles.Add(savedFile); } private void _session_SourceDisabled(object sender, EventArgs e) { _tcs.SetResult(_imageFiles); // also check for return codes _session.CurrentSource.Close(); _session.Close(); } }
-
reporter I've got the point. Thank you very much. This is awesome lib.
- Log in to comment