Flutter - 为什么我会收到“未处理的异常:迭代期间并发修改”从数据库查询?

发布于 2025-01-13 01:58:55 字数 2850 浏览 0 评论 0原文

我在理解有关颤振数据库处理的问题时遇到了一些困难(至少我这么认为,因为这就是问题所在)。当我运行我的应用程序时,我收到以下错误消息:

E/flutter (26185): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Concurrent modification during iteration: Instance(length:13) of '_GrowableList'.
E/flutter (26185): #0      ListIterator.moveNext (dart:_internal/iterable.dart:336:7)
E/flutter (26185): #1      _MyHomePageState._processBle.<anonymous closure> (package:blescanner/screens/home_view.dart:283:27)
E/flutter (26185): <asynchronous suspension>

我花了很多精力试图找出原因。引用的第 283 行是 MyHomePage 中的“for (var element in list){”行,但据我所知,我并没有尝试在任何地方修改该列表。一段时间后,我开始逐行注释以查找问题的原因,结果发现当我注释掉“dbHelper.getBlItemLog”调用时,问题消失了。这让我进入了该函数(代码包含在下面),其中问题似乎是数据库查询。我认为这可能是查询期间修改数据库的一些问题,因此我删除了对数据库的所有其他调用,但问题仍然存在。数据库查询怎么会导致这种问题呢?我就是不明白为什么?有人对此有什么见解或建议吗?

来自 MyHomePage(扩展了 Stateful Widget):

  void _processBle() {
    FlutterBluePlus.instance.scanResults.forEach((list) async {
      for (var element in list) {
        String bleName = element.device.name;
        dev.log('Found device: ' + bleName);
        String blItemId = bleName.replaceAll('XXX', '');
        var blItemData = CustomBluetoothItem.fromBle(bleName,
            blItemId,
            element.advertisementData.manufacturerData,
            _geoPos.lat, _geoPos.long
        );
        int tempStatus = blItemData.status;
        try {
          if (blItemData.status > 1) {
            await lock.synchronized(() async {
              dev.log('${DateTime.now()
                  .toIso8601String()} _processBle .. start $bleName');

              //here's where I call the troubling function

              await dbHelper.getBlItemLog(
                  bleName: bleName, startDate: blItemData.sDate)
                  .then((queueItem) async {
                // the stuff in here is commented away for now and thus doesn't matter
              });


              dev.log('${DateTime.now()
                  .toIso8601String()} _processBle .. stop ${element.device
                  .name}');
            });
          }
        } catch (e) {
          dev.log('error : $e');
        }
      }
    });
    firstStartup = false;
    dev.log('_processBle - ### done');
  }

来自我的 dbHelper:

  Future<CustomBluetoothItem?> getBlItemLog({required String bleName, required String startDate}) async {
    Database? db = await database;

   //the following line seems to be where the issue is, since there's no issue if I comment it away.
    
   List<Map<String, dynamic>> maps = await db!.rawQuery('SELECT * FROM ble_table WHERE bleName = ? AND startDate = ? ORDER BY createDate desc limit 1 offset 0',[bleName,startDate]);
    
    if (maps.isNotEmpty) {
      return CustomBluetoothItem.fromJson(maps[0]);
    }
    return null;
  }

I'm having some trouble understanding an issue regarding flutters database handling (at least I assume so since that's where the issue seems to be). When I run my app I get the following error message:

E/flutter (26185): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Concurrent modification during iteration: Instance(length:13) of '_GrowableList'.
E/flutter (26185): #0      ListIterator.moveNext (dart:_internal/iterable.dart:336:7)
E/flutter (26185): #1      _MyHomePageState._processBle.<anonymous closure> (package:blescanner/screens/home_view.dart:283:27)
E/flutter (26185): <asynchronous suspension>

I've put a lot of effort trying to find why this is. The row 283 referenced is my "for (var element in list){"-row in MyHomePage, but to my knowledge I'm not trying to modify that list anywhere. After some time I just started commenting away line after line to find what the cause of the issue and it turns out that it disappeared when I commented away the "dbHelper.getBlItemLog"-call. That led me into that function (code included further down) where the issue seems to be the database query. I thought that it might be some issue with the database being modified during the query, so I removed all other calls to the database, but the issue remained. How can a database query cause this kind of issue? I just can't understand why? does anyone have any kind of insight or suggestion regarding this?

from MyHomePage (which extends Stateful Widget):

  void _processBle() {
    FlutterBluePlus.instance.scanResults.forEach((list) async {
      for (var element in list) {
        String bleName = element.device.name;
        dev.log('Found device: ' + bleName);
        String blItemId = bleName.replaceAll('XXX', '');
        var blItemData = CustomBluetoothItem.fromBle(bleName,
            blItemId,
            element.advertisementData.manufacturerData,
            _geoPos.lat, _geoPos.long
        );
        int tempStatus = blItemData.status;
        try {
          if (blItemData.status > 1) {
            await lock.synchronized(() async {
              dev.log('${DateTime.now()
                  .toIso8601String()} _processBle .. start $bleName');

              //here's where I call the troubling function

              await dbHelper.getBlItemLog(
                  bleName: bleName, startDate: blItemData.sDate)
                  .then((queueItem) async {
                // the stuff in here is commented away for now and thus doesn't matter
              });


              dev.log('${DateTime.now()
                  .toIso8601String()} _processBle .. stop ${element.device
                  .name}');
            });
          }
        } catch (e) {
          dev.log('error : $e');
        }
      }
    });
    firstStartup = false;
    dev.log('_processBle - ### done');
  }

from my dbHelper:

  Future<CustomBluetoothItem?> getBlItemLog({required String bleName, required String startDate}) async {
    Database? db = await database;

   //the following line seems to be where the issue is, since there's no issue if I comment it away.
    
   List<Map<String, dynamic>> maps = await db!.rawQuery('SELECT * FROM ble_table WHERE bleName = ? AND startDate = ? ORDER BY createDate desc limit 1 offset 0',[bleName,startDate]);
    
    if (maps.isNotEmpty) {
      return CustomBluetoothItem.fromJson(maps[0]);
    }
    return null;
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文