即使unconsumedBufferLength为0

时间:2016-02-20 18:55:50

标签: javascript typescript windows-runtime

我正在使用以下代码在UWP WinRT上使用JSON流:

async function connect() {
    let stream: MSStream;
    return new CancellableContext<void>(
        async (context) => {
            // this will be called immediately
            stream = await context.queue(() => getStreamByXHR()); // returns ms-stream object
            await consumeStream(stream);
        },
        {
            revert: () => {
                // this will be called when user cancels the task
                stream.msClose();
            }
        }
    ).feed();
}

async function consumeStream(stream: MSStream) {
    return new CancellableContext<void>(async (context) => {
        const input = stream.msDetachStream() as Windows.Storage.Streams.IInputStream;
        const reader = new Windows.Storage.Streams.DataReader(input);
        reader.inputStreamOptions = Windows.Storage.Streams.InputStreamOptions.partial;

        while (!context.canceled) {
            const content = await consumeString(1000);
            // ... some more codes
        }

        async function consumeString(count: number) {
            await reader.loadAsync(count); // will throw when the stream gets closed
            return reader.readString(reader.unconsumedBufferLength);
        }
    }).feed();
}

此处,有关InputStreamOptions.partial的文件说:

  

当一个或多个字节可用时,异步读取操作完成。

但是,即使reader.loadAsync为0,reader.unconsumedBufferLength也会完成,这会导致CPU负载。这是API错误还是我可以阻止此行为,以便loadAsync只有在unconsumedBufferLength大于0时才能完成?

PS:以下是纯JS的复制品:https://github.com/SaschaNaz/InputStreamOptionsBugRepro

1 个答案:

答案 0 :(得分:1)

  

这是API错误还是我可以阻止此行为,以便只有当unconsumedBufferLength大于0时才能完成loadAsync

最喜欢它也在流结尾处完成。因此,在这种情况下,unconsumedBufferLength将为零,需要照顾。

事实上,https://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.streams.datareader.aspx的示例显示了类似的内容(诚然不使用该选项):

            // Once we have written the contents successfully we load the stream.
            await dataReader.LoadAsync((uint)stream.Size);

            var receivedStrings = "";

            // Keep reading until we consume the complete stream.
            while (dataReader.UnconsumedBufferLength > 0)