如何使用任务延迟而不是Windows Silverlight应用程序中的线程睡眠

问题描述 投票:0回答:1

在我的Windows Silverlight电话应用程序中,我单击一个按钮扫描条形码,然后扫描条形码成功,但是每当我再次按下该按钮进行扫描时,都会出现一个奇怪的异常。

未处理System.Reflection.TargetInvocationException

消息:System.Windows.ni.dll中发生了类型为'System.Reflection.TargetInvocationException'的未处理的异常其他信息:调用的目标已引发异常。

我已经搜索了很多,并且有一个想法可能是由于该扫描函数中的Thread.Sleep代码所致。

我如何使用Task.delay而不是Thread.sleep,这将解决问题吗?我认为这是一个线程问题,我对多线程不是很好。

这是我的代码:

 private async void ScanClick(object sender, EventArgs e)
    {

        var scanner = new MobileBarcodeScanner();
        var check = true;
        var opts = new MobileBarcodeScanningOptions();
        opts.PossibleFormats = new List<BarcodeFormat>
        {
            BarcodeFormat.EAN_8,
            BarcodeFormat.EAN_13
        };
        Thread MT = new Thread(new ThreadStart(delegate
        {
            while (check)
            {
                scanner.AutoFocus();
                Thread.Sleep(autoFocusInterval);//value of autoFocus is 2000
            }
        }));
        MT.Start();

        var result = await scanner.Scan(opts);
        if(result!=null)
        {
            if(MT.IsAlive)
            {
                MT.Abort();//I try to abort to prevent the error, but it doesn't help.
            }
            MessageBox.Show("Scanned code : " + result.Text);
            result = null;
            MT = null;
            scanner = null;
            opts = null;
            check = false;
        }


    }

注意:即使我只是第一次单击扫描按钮并打开扫描仪,然后不扫描任何东西而按回去,然后第二次返回却产生异常。

所以无论如何第一次都很好,但是每隔第二次进入扫描仪都会产生异常。

需要延迟的原因:

[在扫描我正在使用的库(ZXing.Net.Mobile)时不会自动自动对焦,因此,直到条形码获得扫描结果之前,我必须每2秒手动启动自动对焦。

c# multithreading windows-phone-8 task-parallel-library barcode-scanner
1个回答
1
投票

异常听起来像是scanner.Autofocus或Thread.Sleep会在您不处理的线程内引发异常。

要执行此操作并使用首选的Task.Delay,您可以按照以下方式重写代码,该代码也使用了更现代的Task方法,而不是直接使用线程:

var cts = new CancellationTokenSource();
var ct = cts.Token;
var mtTask = Task.Run(async () =>
{
  while (true) // Loop will be exited when cts.Cancel is called as Task.Delay will respond with an OperationCancelledException
  {
    scanner.AutoFocus();
    await Task.Delay(autoFocusInterval, ct);
   }
 }, ct);

 var result = await scanner.Scan(opts);
 cts.Cancel();
 try
 {
   await mtTask;
 }
 catch (OperationCancelledException)
 {}
 if (result != null)
 {
   MessageBox.Show("Scanned code : " + result.Text);
 }

[另外,您可以在事件处理程序之外定义cts变量,允许您在窗体关闭时取消任务,等等。如果scan.Scan方法的重载接受CancellationToken,则应使用此重载并为其提供ct取消令牌,因此您也可以取消扫描任务。

© www.soinside.com 2019 - 2024. All rights reserved.