溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Dart怎么實現(xiàn)多任務(wù)并行

發(fā)布時間:2023-05-11 15:33:17 來源:億速云 閱讀:340 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Dart怎么實現(xiàn)多任務(wù)并行”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

Isolate(隔離區(qū)域)

Dart 是一種支持多任務(wù)并行的編程語言,它提供了多種機制來實現(xiàn)并發(fā)和并行。下面是 Dart 實現(xiàn)多任務(wù)并行的幾種方式:

Dart 中的 Isolate 是一種輕量級的并發(fā)機制,類似于線程。每個隔離區(qū)域都是獨立的內(nèi)存空間,每個隔離區(qū)域都有自己的內(nèi)存空間和執(zhí)行線程,因此不同的隔離區(qū)域之間可以獨立地執(zhí)行代碼,每個隔離區(qū)都在自己的核心上運行,不會阻塞其他 Isolate。從而實現(xiàn)并發(fā)。但是有一點需要注意它們之間不能直接共享數(shù)據(jù),必須通過消息傳遞來實現(xiàn)。

下面是一個簡單的示例代碼,展示了如何使用Isolate在Dart中實現(xiàn)并發(fā)執(zhí)行:

import 'dart:isolate';
void main() async {
  // 創(chuàng)建兩個隔離區(qū)域
  final isolate1 = await Isolate.spawn(runIsolate, 1);
  final isolate2 = await Isolate.spawn(runIsolate, 2);
  // 等待隔離區(qū)域執(zhí)行完畢
  await Future.wait([isolate1.exitCode, isolate2.exitCode]);
}
void runIsolate(int id) {
  // 隔離區(qū)域中執(zhí)行的代碼
  print('Isolate $id is running');
}

在上面的示例中,我們首先使用Isolate.spawn函數(shù)創(chuàng)建兩個隔離區(qū)域,每個隔離區(qū)域都會執(zhí)行runIsolate函數(shù),并傳入不同的參數(shù)(1和2)。runIsolate函數(shù)是隔離區(qū)域中實際執(zhí)行的代碼,它只是簡單地打印一條信息。

在創(chuàng)建完隔離區(qū)域之后,我們使用Future.wait函數(shù)等待隔離區(qū)域執(zhí)行完畢。這里的exitCode屬性返回隔離區(qū)域的退出代碼,如果代碼成功執(zhí)行,它將返回0。

當我們運行上面的代碼時,我們會看到如下輸出:

Isolate 1 is running
Isolate 2 is running

可以看到,兩個隔離區(qū)域幾乎同時啟動并執(zhí)行,實現(xiàn)了并發(fā)執(zhí)行的效果。這只是Isolate的簡單示例,您可以使用它來執(zhí)行更復(fù)雜的并發(fā)任務(wù),例如使用多個Isolate同時下載多個文件,或在不同的隔離區(qū)域中執(zhí)行計算密集型任務(wù),以提高性能等。

async/await

在Dart中,async/await使用的是Future對象來實現(xiàn)異步操作。當我們在一個函數(shù)或方法前面加上async關(guān)鍵字時,這個函數(shù)就變成了一個異步函數(shù)。在異步函數(shù)中使用await關(guān)鍵字可以等待其他異步操作的結(jié)果,而不會阻塞當前函數(shù)的執(zhí)行。

下面是一個使用async/await實現(xiàn)異步并發(fā)的Demo代碼,它會同時下載兩個URL的內(nèi)容,并在兩個下載操作都完成后將結(jié)果打印出來:

import 'dart:async';
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
  final url1 = 'https://www.example.com';
  final url2 = 'https://www.example.net';
  final result1 = downloadUrl(url1);
  final result2 = downloadUrl(url2);
  final results = await Future.wait([result1, result2]);
  for (final result in results) {
    print(result);
  }
}
Future<String> downloadUrl(String url) async {
  final httpClient = HttpClient();
  final request = await httpClient.getUrl(Uri.parse(url));
  final response = await request.close();
  final contents = await response.transform(utf8.decoder).join();
  httpClient.close();
  return contents;
}

在上面的代碼中,downloadUrl方法是一個異步函數(shù),它使用HttpClient類下載給定URL的內(nèi)容。在main函數(shù)中,我們使用Future.wait方法來等待兩個下載操作都完成,然后打印結(jié)果。由于result1和result2是同時進行的,因此整個過程是并發(fā)的。

Stream

Dart 中的 Stream 是一種基于事件的異步編程模型,它可以處理連續(xù)的異步事件流。使用 Stream 可以將一個長時間運行的任務(wù)分解成多個小任務(wù),并且可以在每個小任務(wù)完成后將結(jié)果推送到事件流中,這樣其他任務(wù)就可以異步地獲取結(jié)果。

下面是一個使用Stream實現(xiàn)異步并發(fā)的Demo代碼,它會從兩個URL下載數(shù)據(jù)并將結(jié)果打印出來:

import 'dart:async';
import 'dart:convert';
import 'dart:io';
Future<void> main() async {
  final url1 = 'https://www.example.com';
  final url2 = 'https://www.example.net';
  final stream1 = downloadUrl(url1);
  final stream2 = downloadUrl(url2);
  await for (final result in StreamGroup.merge([stream1, stream2])) {
    print(result);
  }
}
Stream<String> downloadUrl(String url) async* {
  final httpClient = HttpClient();
  final request = await httpClient.getUrl(Uri.parse(url));
  final response = await request.close();
  await for (final chunk in response.transform(utf8.decoder)) {
    yield chunk;
  }
  httpClient.close();
}

在上面的代碼中,downloadUrl方法返回一個Stream對象,用于異步下載給定URL的內(nèi)容。在main函數(shù)中,我們使用StreamGroup.merge方法將兩個下載流合并為一個,并使用await for循環(huán)逐個處理下載結(jié)果。

需要注意的是,在downloadUrl方法中,我們使用yield關(guān)鍵字來逐個將下載的數(shù)據(jù)塊發(fā)送到Stream中,這樣就可以在下載過程中不斷地將數(shù)據(jù)發(fā)送出去,而不用等到所有數(shù)據(jù)都下載完成后再一次性發(fā)送。這也是Stream在處理大量異步事件時的優(yōu)勢之一。

Compute Function

Dart 中的 Compute Function 是一種可以在獨立的 Isolate 中運行的函數(shù),它可以接收輸入?yún)?shù)并返回結(jié)果。使用 Compute Function 可以將一個計算密集型的任務(wù)分解成多個小任務(wù),在每個小任務(wù)中使用 Compute Function 來并行地計算結(jié)果,最終將結(jié)果合并起來。

下面是一個使用Compute Function實現(xiàn)異步并發(fā)的Demo代碼,它會計算兩個斐波那契數(shù)列,并將結(jié)果打印出來:

import 'dart:async';
import 'package:flutter/foundation.dart';
Future<void> main() async {
  final result1 = compute(fibonacci, 40);
  final result2 = compute(fibonacci, 41);
  final results = await Future.wait([result1, result2]);
  for (final result in results) {
    print(result);
  }
}
int fibonacci(int n) {
  if (n == 0) return 0;
  if (n == 1) return 1;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

在上面的代碼中,我們使用compute函數(shù)將斐波那契數(shù)列的計算任務(wù)交給后臺隔離線程執(zhí)行,然后使用Future.wait方法等待兩個任務(wù)都完成后打印結(jié)果。

需要注意的是,在使用compute函數(shù)時,傳遞給它的函數(shù)必須是頂層函數(shù)或靜態(tài)函數(shù),因為后臺隔離線程無法訪問非靜態(tài)變量或?qū)嵗兞俊?/p>

“Dart怎么實現(xiàn)多任務(wù)并行”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI