2012-04-24 25 views
6

編輯以使問題更清楚。作爲工人的鏢分離物

我正在嘗試在Dart中使用Isolates(或Web Workers)。我可以找到主線程和隔離線程之間通信的唯一方法是發送從主線程調用&然後。但是,這是主線程將一些數據傳遞給隔離區的一種好方法。

如果我希望隔離區成爲生成信息的隔離區,該怎麼辦?就像一個遊戲引擎,它可以完成工作中的所有物理,然後將更新後的世界信息發送到主線程?在JavaScript中,您可以隨時發送數據。 Dart有效嗎?或者我是否仍然需要等待主線程給我打電話,然後傳給它?

P.S.我想知道,是否電話&然後封鎖線程,直到答覆完成或不?

回答

3

警告:此代碼僅適用於飛鏢的舊版本。它不適用於Dart 1.0或更高版本。

正如你所提到的發送消息到隔離區,你需要有一個sendport的句柄。

#import('dart:isolate'); 

main() { 
    SendPort sendPort = spawnFunction(doWork); 
    sendPort.call("hey 1").then((String res) => print("result was: [$res]")); 
    sendPort.call("hey 2").then((String res) => print("result was: [$res]")); 
} 

doWork() { 
    port.receive((msg, reply) { 
    msg = "msg $msg"; 
    reply.send(msg); 
    }); 
} 

但是由於鏢主線程本身就是一種隔離您可以通過使用全球端口功能將數據發送給它:

#import('dart:isolate'); 
#import('dart:io'); 

main() { 
    port.receive((data, reply) { 
     // in here you can access objects created in the main thread 
     print("handle [${data['text']}] for index ${data['index']}"); 
    }); 

    SendPort workPort = spawnFunction(doWork); 
    workPort.send("msg", port.toSendPort()); 
} 

doWork() { 
    port.receive((msg, reply) { 
     int i = 0; 
     new Timer.repeating(1000, (Timer timer) { 
     i++; 
     var data = { 
      "text": "$msg $i", 
      "index": i 
     }; 
     print("sending $data"); 
     reply.send(data); 
     }); 
    }); 
} 

注意有什麼可以送回去一定的限度以及在分離株之間以及目前的分離株在JS和VM上的作用不同。目前的限制很好地描述了here

+0

但有什麼,如果我想我的隔離生成/更新數據?就像一個遊戲引擎。它應該運行所有的計算,然後傳遞遊戲中對象的更新狀態。有沒有一個有效的機制呢,還是我必須在Isolates之上構建它? – Pijusn 2012-04-25 04:25:55

+0

@Pius你不能將引用發送到隔離區,所有處理的數據都按照此處所述進行復制http://api.dartlang.org/dart_isolate/SendPort.html#send – 2012-04-25 05:24:08

+0

我不是在談論引用。我在談論數據。你有沒有在JavaScript中使用Web Workers?您可以隨時從工作人員發送數據。儘可能多的,如你所願。工作人員可以在沒有監聽主線程的情況下工作併發送數據,而主線程可以簡單地使用回調函數接收數據。我在說隔離中的self.postMessage函數等價。 – Pijusn 2012-04-25 14:54:51

0

您現在可以使用MessageBox類來相互溝通。該代碼在收到MessageBox的接收端後立即從Isolate代碼發送消息。主線程接收Isolate發送的消息並將其打印在Dartium的控制檯上。一旦你收到了Sink,你就可以啓動你的遊戲邏輯並使用接收到的接收器對象發送更新。

import 'dart:html'; 
import 'dart:isolate'; 

void main() { 
    IsolateSink isolateSink = streamSpawnFunction(myIsolateEntryPoint); 
    MessageBox isolateMessageBox = new MessageBox(); 
    isolateSink.add(isolateMessageBox.sink); 
    isolateMessageBox.stream.listen((String data) { 
    print(data); 
    }); 
} 

void myIsolateEntryPoint() { 
    stream.listen((IsolateSink messageBoxSink) { 
    messageBoxSink.add("Test"); 
    }); 
} 
3

從DART 1.0,可以使用隔離這樣的:

import 'dart:isolate'; 
import 'dart:async'; 

void doStuff(SendPort sendPort) { 
    print('hi from inside isolate'); 
    ReceivePort receivePort = new ReceivePort(); 
    sendPort.send(receivePort.sendPort); 

    receivePort.listen((msg) { 
    print('Received in isolate: [$msg]'); 
    sendPort.send('ECHO: $msg'); 
    }); 

} 

void main() { 
    SendPort sendPort; 

    ReceivePort receive = new ReceivePort(); 
    receive.listen((msg) { 
    if (sendPort == null) { 
     sendPort = msg; 
    } else { 
     print('From isolate: $msg'); 
    } 
    }); 

    int counter = 0; 

    Isolate.spawn(doStuff, receive.sendPort).then((isolate) { 
    new Timer.periodic(const Duration(seconds:1), (t) { 
     sendPort.send('Count is ${counter++}'); 
    }); 
    }); 
} 
1

這裏是父創建了兩個分離,然後兩種分離也與父進程互相交談沿一個例子。

父代碼:

import 'dart:isolate'; 
import 'dart:html'; 
import 'dart:async'; 

main() { 
    querySelector('#output').text = 'Your Dart app is running.'; 
    int counter = 0; 

    // Parent - Child 1 
    SendPort csendPort1; 
    ReceivePort receivePort1 = new ReceivePort(); 
    // Parent - Child 2 
    SendPort csendPort2; 
    ReceivePort receivePort2 = new ReceivePort(); 
    // Child1 - Child2 
    SendPort csendPort11; 
    SendPort csendPort12; 

    // Child 1 
    receivePort1.listen((msg) { 
    if (csendPort1 == null) { 
     csendPort1 = msg; 
    } else if (csendPort11 == null) { 
     csendPort11 = msg; 
    } else { 
     print('$msg');`enter code here` 
    } 
    }); 

    bool child1 = false; 
    Isolate.spawnUri(Uri.parse('child.dart'), [], receivePort1.sendPort).then((isolate) { 
    print('Child 1 isolate spawned'); 
    new Timer.periodic(const Duration(milliseconds: 500), (t) { 
     if (csendPort11 != null && csendPort12 != null && child1 == false) { 
     child1 = true; 
     csendPort12.send(csendPort11); 
     } else { 
     csendPort1.send('Parent-Child1: ${counter++}'); 
     } 
    }); 
    }); 

    // Child 2 
    receivePort2.listen((msg) { 
    if (csendPort2 == null) { 
     csendPort2 = msg; 
    } else if (csendPort12 == null) { 
     csendPort12 = msg; 
    } else { 
     print('$msg'); 
    } 
    }); 

    bool child2 = false; 
    Isolate.spawnUri(Uri.parse('child.dart'), [], receivePort2.sendPort).then((isolate) { 
    print('Child 2 isolate spawned'); 
    new Timer.periodic(const Duration(milliseconds: 500), (t) { 
     if (csendPort11 != null && csendPort12 != null && child2 == false) { 
     child2 = true; 
     csendPort11.send(csendPort12); 
     } else { 
     csendPort2.send('Parent-Child2: ${counter++}'); 
     } 
    }); 
    }); 
} 

兒童代碼:

import 'dart:isolate'; 
import 'dart:async'; 

int pcounter = 0; 
int ccounter = 0; 

SendPort csendPort; 
void handleTimeout() { 
    csendPort.send("${ccounter++}"); 
} 

main(List<String> args, SendPort psendPort) { 
    // Parent Comm 
    ReceivePort creceivePort1 = new ReceivePort(); 
    psendPort.send(creceivePort1.sendPort); 

    creceivePort1.listen((msg) { 
    psendPort.send('Child-Parent: ${pcounter++} - ${msg}'); 
    }); 

    // Child-Child Comm 
    ReceivePort creceivePort2 = new ReceivePort(); 
    psendPort.send(creceivePort2.sendPort); 

    creceivePort2.listen((msg) { 
    if (csendPort == null) { 
     csendPort = msg; 
     csendPort.send("${ccounter++}"); 
    } else { 
     print("Child-Child: $msg"); 
     var duration = const Duration(milliseconds: 2000); 
     new Timer(duration, handleTimeout); 
    } 
    }); 
} 

HTML代碼:

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <meta name="scaffolded-by" content="https://github.com/google/stagehand"> 
    <title>WebIsolateTest</title> 
    <link rel="stylesheet" href="styles.css"> 
    <script defer src="main.dart" type="application/dart"></script> 
    <script defer src="packages/browser/dart.js"></script> 
</head> 

<body> 

    <div id="output"></div> 

</body> 
</html> 
+0

上述代碼適用於dart sdk版本1.14.2以及Chrome,Firefox和IE11 – user2569304 2016-03-07 18:34:21