Асинхронное сканирование документов с помощью TWAIN

У меня есть программа C#, которая использует TwainDotNet для сканирования и получения изображений со сканера Fujitsu. У меня есть рабочий код, но я хочу выполнять сканирование и передачу изображений асинхронно, потому что графический интерфейс зависает до завершения процесса сканирования.

Я попытался следовать рекомендациям из это сообщение принятое решение с использованием этого кода:

public void StartScanning()
{
    // Run the scanner from a separate thread
    Task.Run(() => ScanThread());
}

private void ScanThread()
{
    // Instantiate the Twain object and hookup event handlers
    Twain twain = new Twain(new WinFormsWindowMessageHook(new Form()));
    twain.TransferImage += Twain_TransferImage;
    twain.ScanningComplete += Twain_ScanningComplete;

    // Start the scanning process by passing along pre-defined scan settings
    twain.StartScanning(GetScanSettings());
}

Код внутри ScanThread() технически правильный, потому что он работает вне вызова Task.Run() (это означает, что он нормально работает в потоке графического интерфейса). Однако ScanThread() не работает, если вызывается из нового потока. Аппаратное обеспечение сканера никогда не начинает сканировать изображения, не говоря уже о их передаче.

Кто-нибудь знает конкретный способ асинхронного сканирования и передачи изображений с помощью TWAIN?


person Richard    schedule 06.07.2017    source источник


Ответы (1)


Я подозреваю, что «простой» ответ «вы не можете».

Более сложный ответ заключается в том, что "twain" (или, возможно, "GetScanSettings" - что это делает?), вероятно, потребует выполнения операций в потоке пользовательского интерфейса.

См.: Сканирование TwainDotNet с использованием TWAIN и BackgroundWorker

Тем не менее, это может быть возможно, используя код, который у вас есть, за исключением того, что создаваемая вами форма, вероятно, почти сразу выходит за рамки, если ссылки слабые (например, делегат события).

Попробуйте добавить список или словарь Thread Safe, добавить в него свою форму при ее создании и удалить ее в Twain_ScanningComplete.

Хм. На самом деле, попробуй

private ConcurrentDictionary<Twain,Form> m_References = new ConcurrentDictionary<Twain,Form>();


private void ScanThread()
{
    // Instantiate the Twain object and hookup event handlers
    Form frm = new Form();
    Twain twain = new Twain(new WinFormsWindowMessageHook(frm));
    m_References.Add(twain, frm);

    twain.TransferImage += Twain_TransferImage;
    twain.ScanningComplete += Twain_ScanningComplete;

    // Start the scanning process by passing along pre-defined scan settings
    twain.StartScanning(GetScanSettings());
}


private void Twain_ScanningComplete(object sender, ScanningCompleteEventArgs args)
{
    Form frm;
    m_References.TryRemove((Twain) sender, out frm);
    if(null != frm)
    {
       frm.Close();
    }
}
person Roger Willcocks    schedule 06.07.2017
comment
Спасибо за подробное предложение. Я попытался это сделать, но результат был тот же — аппаратное обеспечение сканера никогда не запускается. Я читал старые сообщения о том, что асинхронная передача изображений возможна и невозможна, и подумал, что попробую в 2017 году. - person Richard; 07.07.2017
comment
И просто для уточнения: GetScanSettings() — это удобный метод для возврата объекта ScanSettings, специфичного для TwainDotNet. Объект представляет собой контейнер для полей, которые могут использоваться или не использоваться конкретным сканером. - person Richard; 07.07.2017
comment
Можете ли вы где-нибудь сериализовать результат GetScanSettings и сравнить их, просто чтобы увидеть, есть ли разница в результате? - person Roger Willcocks; 08.07.2017