1

I have the code below for scanning but When i press the button to start scanning, the windows form freezes and i can not move the form or minimizie/colse it until the process will be finished! i'm new in working with Thread but i tried to add Thread andi couldn't solve the problem. Does anyone know to where (how) can i write a Thread to release my form from freezing? Thanks.

public Bitmap GetBitmapFromRawData(int w, int h, byte[] data)
{
   //Do sth
 }
    //button to start the scan proccess
    private void button1_Click(object sender, EventArgs e)
    {
      try
      {
        var deviceManager = new DeviceManager();
        for ( int i = 1; i <= deviceManager.DeviceInfos.Count; i++ ) 
        {
          if ( deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType ) 
          {
            continue;
          }
          lstListOfScanner.Items.Add(deviceManager.DeviceInfos[i].Properties["Name"].get_Value());
        }
      }
      catch ( COMException ex )
      {
        MessageBox.Show(ex.Message);
      }

      try
      {
        var deviceManager = new DeviceManager();

        DeviceInfo AvailableScanner = null;

        for ( int i = 1; i <= deviceManager.DeviceInfos.Count; i++ ) 
        {
          if ( deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType ) // Skip device If it is not a scanner
          {
            continue;
          }

          AvailableScanner = deviceManager.DeviceInfos[i];
          break;
        }
        var device = AvailableScanner.Connect(); 
        var ScanerItem = device.Items[1];
        var imgFile = (ImageFile)ScanerItem.Transfer();
        var data = (byte[])imgFile.FileData.get_BinaryData();
        var bitmap = GetBitmapFromRawData(imgFile.Width, imgFile.Height, data);
        var Path = @"C:\....\ScanImg.jpg"; 
        bitmap.Save(Path, ImageFormat.Jpeg);
      }
      catch ( COMException ex )
      {
        MessageBox.Show(ex.Message);
      }
Flash
  • 85
  • 10
  • Please post the version _with_ Thread that didn't work for you. Maybe we can fix it. That the posted code will block your UI Thread is quite obvious. Also, you could take a solution with Task Async Pattern into consideration. This is in windows forms, right? – Fildor Nov 15 '19 at 09:36

1 Answers1

2

Try adopting the async/await approach:

private async void button1_Click(object sender, EventArgs e)
{
    try
    {
        object[] items = await Task.Run<object[]>(() =>
        {
            var deviceManager = new DeviceManager();
            List<object> result = new List<object>();
            for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++)
            {
                if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType)
                {
                    continue;
                }
                result.Add(deviceManager.DeviceInfos[i].Properties["Name"].get_Value());
            }
            return result.ToArray();
        });
        foreach (var item in items)
        {
            lstListOfScanner.Items.Add(item);
        }
    }
    catch (COMException ex)
    {
        MessageBox.Show(ex.Message);
    }

    try
    {
        await Task.Run(() =>
        {
            var deviceManager = new DeviceManager();

            DeviceInfo AvailableScanner = null;

            for (int i = 1; i <= deviceManager.DeviceInfos.Count; i++)
            {
                if (deviceManager.DeviceInfos[i].Type != WiaDeviceType.ScannerDeviceType) // Skip device If it is not a scanner
                {
                    continue;
                }

                AvailableScanner = deviceManager.DeviceInfos[i];
                break;
            }
            var device = AvailableScanner.Connect();
            var ScanerItem = device.Items[1];
            var imgFile = (ImageFile)ScanerItem.Transfer();
            var data = (byte[])imgFile.FileData.get_BinaryData();
            var bitmap = GetBitmapFromRawData(imgFile.Width, imgFile.Height, data);
            var Path = @"C:\....\ScanImg.jpg";
            bitmap.Save(Path, ImageFormat.Jpeg);
        });
    }
    catch (COMException ex)
    {
        MessageBox.Show(ex.Message);
    }
}
max
  • 466
  • 3
  • 7
  • 2
    `lstListOfScanner.Items.Add(deviceManager.DeviceInfos[i].Properties["Name"].get_Value());` That would modify UI Elements from a different Thread than the one they have been created on ... – Fildor Nov 15 '19 at 09:57
  • @Max Thanks both, but i would like to know is it possible to do it also with using a Thread t = new Thread(...) ? – Flash Nov 15 '19 at 13:11
  • @Fildor Thaks for the reply.How can i release lstListOfScanner.Items.Add(deviceManager.DeviceInfos[i].Properties["Name"].get_Value()); with using a thread? – Flash Nov 15 '19 at 13:48
  • @arash6657 It is possible but much more complicated. The TAP for CPU-Bound operations _is_ in principle using a thread (from the threadpool) while abstracting all the complicated stuff away for you. – Fildor Nov 15 '19 at 13:55
  • @Fildor Thanks.and another question. in the corrected code, how can i scan all pages automatically? now it scann only one page – Flash Nov 15 '19 at 15:54