2014-11-30 4 views
1

파일/하위 폴더를 병렬로 복사하는이 재귀 copyFolder 메서드가 있습니다.WinRT에서 파일의 병렬 또는 순차 복사

copyFileIfNewerAsync = function(sourceFile, destFolder) { 
    return destFolder.tryGetItemAsync(sourceFile.name).then(function(destFile) { 
    if (destFile) { 
     return WinJS.Promise.join({ 
     sourceProperties: sourceFile.getBasicPropertiesAsync(), 
     destProperties: destFile.getBasicPropertiesAsync() 
     }).then(function(_arg) { 
     var destProperties, sourceProperties; 
     sourceProperties = _arg.sourceProperties, destProperties = _arg.destProperties; 
     if (sourceProperties.size !== destProperties.size && sourceProperties.dateModified > destProperties.dateModified) { 
      logger.debug("Updating " + destFolder.path + "\\" + destFile.name); 
      return sourceFile.copyAsync(destFolder, sourceFile.name, NameCollisionOption.replaceExisting); 
     } else { 
      return logger.trace("" + destFolder.path + "\\" + destFile.name + " up-to-date (" + destProperties.dateModified + ")"); 
     } 
     }); 
    } else { 
     logger.debug("Copying " + sourceFile.name + " to " + destFolder.path); 
     return sourceFile.copyAsync(destFolder, sourceFile.name, NameCollisionOption.replaceExisting); 
    } 
    }); 
}; 
copyFolderAsync = function(destFolder, sourceFolder) { 
    return destFolder.createFolderAsync(sourceFolder.name, CreationCollisionOption.openIfExists).then(function(destSubFolder) { 
    return sourceFolder.getItemsAsync().then(function(items) { 
     return WinJS.Promise.join(items.map(function(item) { 
     if (item instanceof Windows.Storage.StorageFile) { 
      return copyFileIfNewerAsync(item, destSubFolder); 
     } else { 
      return copyFolderAsync(destSubFolder, item); 
     } 
     })); 
    }); 
    }); 
}; 

이것은 시스템에 상당한 영향을줍니다. 순차적 복사 방식은 시스템에 스트레스가 적고 결국에는 더 빨라지 는가?

그렇다면 순차적으로 실행되도록 코드를 리팩토링해야하는 이유는 무엇입니까?

이 다음 낮은 프리 오에서 모든 다운로드를 예약해야 WinJS.Scheduler

preloadAsync = (serialNumbers, expert) -> 
    assert(expert) 
    assert(serialNumbers) 
    serialNumbers = [serialNumbers] unless Array.isArray(serialNumbers) 
    preloadPromise?.cancel() 
    preloadPromise = serialNumbers.reduce((p, serialNumber) -> 
     p.then(WinJS.Utilities.Scheduler.schedulePromiseBelowNormal) 
     .then() -> 
     preloadOneAsync(serialNumber, expert) 
     .then null, (error) -> 
     if error.name isnt "Canceled" 
      logger.error("Could not create preloaded inspection #{serialNumber}", error) 
    , WinJS.Promise.as()) 

에 대한

갱신?

답변

1

예, 비동기 호출이 자체 스레드에서 스핀 할 때마다 너무 많은 병렬 작업으로 파일 시스템이 오버로드되는 것을 상상해보십시오. 합리적인 접근 방법은 각 폴더를 병렬로 실행하고 각 폴더 내의 파일을 순차적으로 실행시키는 것입니다.

트릭은 각 비동기 파일 복사본을 순차적으로 실행하는 것입니다. 이를 위해 입력 매개 변수의 배열에서 순차적으로 연결하는 유용한 패턴이 있습니다. 1208 페이지 (부록 A)에 설명 된 입력 매개 변수는 무료 전자 책 Programming Windows Store Apps with HTML, CSS, and JavaScript, 2nd Edition입니다.

귀하의 경우에는 sourceFolder.getFoldersAsync를 별도로 호출하고 copyFolderAsync를 호출하는 결과를 반복하고 싶을 것입니다. 그런 다음 sourceFolder.getFilesAsync를 호출하여 파일 배열을 가져옵니다. 이것은 패턴에 표시된대로 array.reduce 메서드와 함께 사용할 수 있습니다.이 메서드는 누적 된 약속 배열을 한 번에 하나씩 만듭니다. 책의 코드를 사용하면 "op"는 copyFileIfNewerAsync를 호출합니다.

여기 내 예제에서 수정 된 코드는 단지 그것을 보여주고있다 :

//This op function attached other arguments to each call 
var op = function (file) { return copyFileIfNewerAsync(file); }; 

//The arguments we want to process are in "files" from getFilesAsync 

//This code creates a parameterized promise chain from the items array and the async call 
//in op. By using WinJS.Promise.as for the initializer we can just call p.then inside 
//the callback. 
var endPromise = files.reduce(function (p, file) { 
    return p.then(function (r) { 
     //The first result from WinJS.Promise.as will be undefined, so skip logging 
     if (r !== undefined) { App.log("operation completed with results = " + r) }; 

     return op(file); 
    }); 
}, WinJS.Promise.as()); 

//endPromise is fulfilled with the last operation's results when the whole chain is complete. 
endPromise.done(function (r) { 
    App.log("Final promise complete with results = " + r); 
}); 
+0

감사 Kraig. 그것을 밖으로 시도하고 다시 여기에 올 것이다. – philk

+0

Kraig가 일정 시간 동안 일정 잡기 위해 UI 유휴 상태에서 파일을 복사하기 만하면 WinJS.Utilities.Scheduler.schedulePromiseBelowNormal을 사용할 수 있습니까? – philk

+0

예, Windows의 사람들과 확인한 결과, 우선 순위가 낮은 JS 콜백 내에서 생성 된 WinRT 비동기 호출이 더 낮은 우선 순위로 실행됩니다. 엄밀히 말하면 JS 콜백의 CoreDispatcher 우선 순위를 상속합니다. 따라서 유휴 상태에서 실행되도록 스케줄러를 사용하면 UI 응답 성 문제를 방지 할 수 있습니다. –