使用 Isolate 对列表进行排序
Use Isolate to sort list
我有一个非原始列表,我想对其进行排序。
当我排序时,UI 线程被阻塞,应用程序冻结了几秒钟。
我试图通过使用 dart 的 Isloate 来避免这种情况 compute function but since the parameter sent to the compute function must be a primitive or a list/map of primitives (send method) 它没有用。
总而言之,有没有什么方法可以在不阻塞 UI 线程的情况下执行列表排序(非原始)?
编辑:澄清 - 我试图通过计算调用一个函数,我传递了一个对象列表(我从第三方插件获得)作为参数,这些对象有一个 属性类型 Iterable 并导致一切失败 - 确保所有类型都是原始类型或 List/Map 个原始类型。根据我收到的答案并将类型从 Iterable 更改为 List 它起作用了。
我不确定我是否理解你的问题,但你可以像这样对非原始元素列表进行排序:
final List<Element> elements = [
Element(id: 1),
Element(id: 7),
Element(id: 2),
Element(id: 0)
];
elements.sort((a, b) => a.compareTo(b));
// or
elements.sort((a, b) => a.id > b.id ? 1 : -1);
这将是一个 print(elements);
输出:
I/flutter ( 7351): [id: 0, id: 1, id: 2, id: 7]
这将是 class Element
class Element {
final int id;
Element({this.id});
@override
String toString() => "id: $id";
int compareTo(Element other) => this.id > other.id ? 1 : -1;
}
编辑:要异步进行,您可以这样做:
Future<List<Element>> asyncSort() async {
print("before sort: $elements");
elements = await compute(_sort, elements);
print("after sort: $elements");
return elements;
}
static List<Element> _sort(List<Element> list) {
list.sort((a, b) => a.compareTo(b));
return list;
}
print("before calling asyncSort(): $elements");
asyncSort();
print("after calling asyncSort(): $elements");
这将是输出:
I/flutter ( 7351): before calling asyncSort(): [id: 1, id: 7, id: 2, id: 0]
I/flutter ( 7351): before sort: [id: 1, id: 7, id: 2, id: 0]
I/flutter ( 7351): after calling asyncSort(): [id: 1, id: 7, id: 2, id: 0]
I/flutter ( 7351): after sort: [id: 0, id: 1, id: 2, id: 7]
Edit2: 如果要将比较函数发送到 compute
,可以使用 Map
或 List
参数使用列表和比较函数并传递它而不是列表,因为 compute
只接受一个参数。这是一个例子:
Future<List<Element>> asyncSort() async {
print("before sort: $elements");
Map args = {"list": elements, "compare": compare};
elements = await compute(_sortWith, args);
print("after sort: $elements");
return elements;
}
static List<Element> _sortWith(Map args) {
List<Element> list = args["list"];
Function(Element a, Element b) compare = args["compare"];
list.sort((a, b) => compare(a, b));
return list;
}
static int compare(Element a, Element b) {
return a.id > b.id ? 1 : -1;
}
这就是我使用计算的方式,只需将所有参数放入一个列表,然后在动态对象列表中调用它:
image = await compute(getCropImage, [copyFaces, streamImg]);
imglib.Image getCropImage(List<dynamic> values) {
var face = values[0]; // copyFaces
var image = values[1]; // streamImg
}
我有一个非原始列表,我想对其进行排序。
当我排序时,UI 线程被阻塞,应用程序冻结了几秒钟。
我试图通过使用 dart 的 Isloate 来避免这种情况 compute function but since the parameter sent to the compute function must be a primitive or a list/map of primitives (send method) 它没有用。
总而言之,有没有什么方法可以在不阻塞 UI 线程的情况下执行列表排序(非原始)?
编辑:澄清 - 我试图通过计算调用一个函数,我传递了一个对象列表(我从第三方插件获得)作为参数,这些对象有一个 属性类型 Iterable 并导致一切失败 - 确保所有类型都是原始类型或 List/Map 个原始类型。根据我收到的答案并将类型从 Iterable 更改为 List 它起作用了。
我不确定我是否理解你的问题,但你可以像这样对非原始元素列表进行排序:
final List<Element> elements = [
Element(id: 1),
Element(id: 7),
Element(id: 2),
Element(id: 0)
];
elements.sort((a, b) => a.compareTo(b));
// or
elements.sort((a, b) => a.id > b.id ? 1 : -1);
这将是一个 print(elements);
输出:
I/flutter ( 7351): [id: 0, id: 1, id: 2, id: 7]
这将是 class Element
class Element {
final int id;
Element({this.id});
@override
String toString() => "id: $id";
int compareTo(Element other) => this.id > other.id ? 1 : -1;
}
编辑:要异步进行,您可以这样做:
Future<List<Element>> asyncSort() async {
print("before sort: $elements");
elements = await compute(_sort, elements);
print("after sort: $elements");
return elements;
}
static List<Element> _sort(List<Element> list) {
list.sort((a, b) => a.compareTo(b));
return list;
}
print("before calling asyncSort(): $elements");
asyncSort();
print("after calling asyncSort(): $elements");
这将是输出:
I/flutter ( 7351): before calling asyncSort(): [id: 1, id: 7, id: 2, id: 0]
I/flutter ( 7351): before sort: [id: 1, id: 7, id: 2, id: 0]
I/flutter ( 7351): after calling asyncSort(): [id: 1, id: 7, id: 2, id: 0]
I/flutter ( 7351): after sort: [id: 0, id: 1, id: 2, id: 7]
Edit2: 如果要将比较函数发送到 compute
,可以使用 Map
或 List
参数使用列表和比较函数并传递它而不是列表,因为 compute
只接受一个参数。这是一个例子:
Future<List<Element>> asyncSort() async {
print("before sort: $elements");
Map args = {"list": elements, "compare": compare};
elements = await compute(_sortWith, args);
print("after sort: $elements");
return elements;
}
static List<Element> _sortWith(Map args) {
List<Element> list = args["list"];
Function(Element a, Element b) compare = args["compare"];
list.sort((a, b) => compare(a, b));
return list;
}
static int compare(Element a, Element b) {
return a.id > b.id ? 1 : -1;
}
这就是我使用计算的方式,只需将所有参数放入一个列表,然后在动态对象列表中调用它:
image = await compute(getCropImage, [copyFaces, streamImg]);
imglib.Image getCropImage(List<dynamic> values) {
var face = values[0]; // copyFaces
var image = values[1]; // streamImg
}