我是多任务的新手,但是我试图了解它是如何运作的。我有以下代码,我认为这将创建一个任务并运行performInitialLoad方法,当完成后,将触发initializeDataHarvester方法。 performInitialLoad工作正常,它确实到达方法的底部,因为我可以看到文本"初始标签数据加载完成"在我的控制台中。但它似乎永远不会触发initializeDataHarvester方法。有什么想法吗?
java.lang.SecurityException: setContextClassLoader
at sun.misc.InnocuousThread.setContextClassLoader(InnocuousThread.java:64)
at org.vertx.java.core.impl.DefaultContext.setTCCL(DefaultContext.java:63)
at org.vertx.java.core.impl.DefaultVertx.setContext(DefaultVertx.java:325)
at org.vertx.java.core.eventbus.impl.DefaultEventBus.sendOrPub(DefaultEventBus.java:743)
at org.vertx.java.core.eventbus.impl.DefaultEventBus.sendOrPub(DefaultEventBus.java:670)
at org.vertx.java.core.eventbus.impl.DefaultEventBus.sendReply(DefaultEventBus.java:528)
at org.vertx.java.core.eventbus.impl.BaseMessage.sendReply(BaseMessage.java:348)
at org.vertx.java.core.eventbus.impl.BaseMessage.reply(BaseMessage.java:156)
at org.vertx.java.core.eventbus.impl.BaseMessage.reply(BaseMessage.java:76)
.........................
at rx.Observable$32.onNext(Observable.java:7187)
at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:130)
at rx.internal.operators.OperatorSubscribeOn$1$1$1.onNext(OperatorSubscribeOn.java:76)
at rx.internal.operators.OperatorMerge$InnerSubscriber.emit(OperatorMerge.java:620)
at rx.internal.operators.OperatorMerge$InnerSubscriber.onNext(OperatorMerge.java:545)
at rx.internal.operators.OperatorMerge$InnerSubscriber.emit(OperatorMerge.java:635)
at rx.internal.operators.OperatorMerge$InnerSubscriber.onNext(OperatorMerge.java:545)
at rx.internal.operators.OperatorMerge$InnerSubscriber.emit(OperatorMerge.java:635)
at rx.internal.operators.OperatorMerge$InnerSubscriber.onNext(OperatorMerge.java:545)
at rx.internal.operators.OperatorMap$1.onNext(OperatorMap.java:54)
...................
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:53)
at com.mongodb.async.client.MongoClientImpl$2$2.onResult(MongoClientImpl.java:144)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:53)
at com.mongodb.operation.OperationHelper$ConnectionReleasingWrappedCallback.onResult(OperationHelper.java:140)
at com.mongodb.operation.MixedBulkWriteOperation$3.onResult(MixedBulkWriteOperation.java:208)
at com.mongodb.operation.MixedBulkWriteOperation$3.onResult(MixedBulkWriteOperation.java:187)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:53)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor$1.onResult(DefaultServer.java:171)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:53)
at com.mongodb.connection.InsertCommandProtocol$1.onResult(InsertCommandProtocol.java:86)
at com.mongodb.connection.InsertCommandProtocol$1.onResult(InsertCommandProtocol.java:79)
at com.mongodb.connection.WriteCommandProtocol.executeBatchesAsync(WriteCommandProtocol.java:154)
at com.mongodb.connection.WriteCommandProtocol.access$000(WriteCommandProtocol.java:37)
at com.mongodb.connection.WriteCommandProtocol$1.onResult(WriteCommandProtocol.java:145)
at com.mongodb.connection.WriteCommandProtocol$1.onResult(WriteCommandProtocol.java:123)
at com.mongodb.connection.CommandResultCallback.callCallback(CommandResultCallback.java:54)
at com.mongodb.connection.CommandResultCallback.callCallback(CommandResultCallback.java:29)
at com.mongodb.connection.CommandResultBaseCallback.callCallback(CommandResultBaseCallback.java:39)
答案 0 :(得分:4)
Task.WhenAll
会立即返回 - 但会返回任务,该任务将在任务完成时完成。你现在忽略了那个回报值。你也没有开始调用WhenAll
的任务,这就是为什么这个任务永远不会完成的原因。
你可以使用:
Task.WhenAll(initialLoad).ContinueWith(...);
...但更好的是,你可以完全避免使用WhenAll
,因为你无论如何都只有一个任务。
您还应该:
使用async / await,此代码将类似于:
private async Task MainTaskLoader()
{
await Task.Run(PerformInitialTagLoad);
InitializeDataHarvester();
}
如果您真的要运行多项内容,可以使用:
private async Task MainTaskLoader()
{
var task1 = Task.Run(PerformInitialTagLoad);
var task2 = Task.Run(SomethingElse);
// Imagine we have many of these...
await Task.WhenAll(task1, task2);
InitializeDataHarvester();
}
理想情况下,您也可以使PerformInitialTagLoad
成为异步方法,请注意 - 这也需要使插入异步。