diff --git a/src/services/services.ts b/src/services/services.ts index 19dd5288721..1e98e29d4cf 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1618,7 +1618,6 @@ namespace ts { export class OperationCanceledException { } export class CancellationTokenObject { - public static None: CancellationTokenObject = new CancellationTokenObject(null) constructor(private cancellationToken: CancellationToken) { diff --git a/src/services/shims.ts b/src/services/shims.ts index 2e8b3eb774d..22c0d3f6065 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -327,7 +327,8 @@ namespace ts { } public getCancellationToken(): CancellationToken { - return this.shimHost.getCancellationToken(); + var hostCancellationToken = this.shimHost.getCancellationToken(); + return new ThrottledCancellationToken(hostCancellationToken); } public getCurrentDirectory(): string { @@ -346,6 +347,29 @@ namespace ts { } } + /** A cancellation that throttles calls to the host */ + class ThrottledCancellationToken implements CancellationToken { + // Store when we last tried to cancel. Checking cancellation can be expensive (as we have + // to marshall over to the host layer). So we only bother actually checking once enough + // time has passed. + private lastCancellationCheckTime = 0; + + constructor(private hostCancellationToken: CancellationToken) { + } + + public isCancellationRequested(): boolean { + var time = Date.now(); + var duration = Math.abs(time - this.lastCancellationCheckTime); + if (duration > 10) { + // Check no more than once every 10 ms. + this.lastCancellationCheckTime = time; + return this.hostCancellationToken.isCancellationRequested(); + } + + return false; + } + } + export class CoreServicesShimHostAdapter implements ParseConfigHost { constructor(private shimHost: CoreServicesShimHost) {