백그라운드 전송 API를 사용하여 네트워크를 통해 파일을 안정적으로 복사합니다. 백그라운드 전송 API는 앱 일시 중단 중에 백그라운드에서 실행되고 앱 종료 이후에도 지속되는 고급 업로드 및 다운로드 기능을 제공합니다. API는 네트워크 상태를 모니터링하고 연결이 끊어지면 전송을 자동으로 일시 중단 및 다시 시작하며, 전송은 Data Sense 인식 및 배터리 감지를 의미합니다. 즉, 다운로드 작업은 현재 연결 및 디바이스 배터리 상태에 따라 조정됩니다. API는 HTTP(S)를 사용하여 대용량 파일을 업로드하고 다운로드하는 데 적합합니다. FTP도 지원되지만 다운로드에 대해서만 지원됩니다.
Note
API는 Windows.Networking.BackgroundTransfer WinUI 3(Windows 앱 SDK) 데스크톱 앱과 UWP 앱에서 작동하는 winRT(Windows 런타임) API입니다. 백그라운드 전송에는 패키지 ID가 필요합니다. 패키지되지 않은 앱은 이 API를 사용할 수 없습니다.
백그라운드 전송은 호출 앱과 별도로 실행되며 주로 비디오, 음악 및 대형 이미지와 같은 리소스에 대한 장기 전송 작업을 위해 설계되었습니다. 이러한 시나리오에서는 앱이 일시 중단된 경우에도 다운로드가 계속 진행되므로 백그라운드 전송을 사용하는 것이 중요합니다.
빠르게 완료할 가능성이 있는 작은 리소스를 다운로드하는 경우 백그라운드 전송 대신 HttpClient API를 사용해야 합니다.
Windows.Networking.BackgroundTransfer 사용하기
백그라운드 전송 기능은 어떻게 작동하나요?
앱이 백그라운드 전송을 사용하여 전송을 시작하면 BackgroundDownloader 또는 BackgroundUploader 클래스 개체를 사용하여 요청이 구성되고 초기화됩니다. 각 전송 작업은 시스템에서 개별적으로 처리되며 호출 앱과는 별개입니다. 진행률 정보는 앱의 UI에서 사용자에게 상태를 제공하려는 경우 사용할 수 있으며, 전송이 발생하는 동안 앱이 데이터에서 일시 중지, 다시 시작, 취소 또는 읽을 수도 있습니다. 시스템에서 전송을 처리하는 방식은 스마트 전원 사용을 촉진하고 연결된 앱이 앱 일시 중단, 종료 또는 갑작스러운 네트워크 상태 변경과 같은 이벤트를 발견할 때 발생할 수 있는 문제를 방지합니다.
Note
앱별 리소스 제약 조건으로 인해 앱에는 지정된 시간에 200개 이상의 전송(DownloadOperations + UploadOperations)이 없어야 합니다. 이 제한을 초과하면 앱의 전송 큐가 복구할 수 없는 상태로 남을 수 있습니다.
애플리케이션이 시작되면 모든 기존 DownloadOperation 및 UploadOperation 개체에서 AttachAsync를 호출해야 합니다. 이렇게 하지 않으면 이미 완료된 전송이 누출되고 결국 백그라운드 전송 기능의 사용이 쓸모 없게 됩니다.
백그라운드 전송을 사용하여 인증된 파일 요청 수행
백그라운드 전송은 각 전송 작업에 대해 기본 서버 및 프록시 자격 증명, 쿠키 및 사용자 지정 HTTP 헤더( SetRequestHeader를 통해)의 사용을 지원하는 메서드를 제공합니다.
이 기능은 네트워크 상태 변경 또는 예기치 않은 종료에 어떻게 적응하나요?
백그라운드 전송 기능은 연결 기능에서 제공하는 연결 및 통신 사업자 데이터 계획 상태 정보를 지능적으로 활용하여 네트워크 상태가 변경될 때 각 전송 작업에 대해 일관된 환경을 유지합니다. 다양한 네트워크 시나리오에 대한 동작을 정의하기 위해 앱은 BackgroundTransferCostPolicy에서 정의한 값을 사용하여 각 작업에 대한 비용 정책을 설정합니다.
예를 들어 작업에 대해 정의된 비용 정책은 디바이스가 데이터 통신 네트워크를 사용할 때 작업을 자동으로 일시 중지해야 함을 나타낼 수 있습니다. 그러면 "무제한" 네트워크에 대한 연결이 설정되면 전송이 자동으로 다시 시작되거나 다시 시작됩니다. 네트워크를 비용으로 정의하는 방법에 대한 자세한 내용은 NetworkCostType을 참조하세요.
백그라운드 전송 기능에는 네트워크 상태 변경을 처리하기 위한 고유한 메커니즘이 있지만 네트워크 연결 앱에 대한 다른 일반적인 연결 고려 사항이 있습니다. 추가 정보는 사용 가능한 네트워크 연결 정보 활용 을 읽어보세요.
참고 사항 모바일 디바이스에서 실행되는 앱의 경우 연결 유형, 로밍 상태 및 사용자의 데이터 요금제에 따라 전송되는 데이터의 양을 모니터링하고 제한할 수 있는 기능이 있습니다. 이 때문에 BackgroundTransferCostPolicy 가 전송을 진행해야 함을 나타내는 경우에도 휴대폰에서 백그라운드 전송이 일시 중지될 수 있습니다.
다음 표는 휴대폰의 현재 상태를 고려할 때 각 BackgroundTransferCostPolicy 값에 대해 휴대폰에서 백그라운드 전송이 허용되는 시기를 나타냅니다. ConnectionCost 클래스를 사용하여 휴대폰의 현재 상태를 확인할 수 있습니다.
| 디바이스 상태 | 제한 없음만 | 기본값 | 늘 |
|---|---|---|---|
| WiFi에 연결됨 | Allow | Allow | Allow |
| 종량제 연결, 로밍 아님, 데이터 제한 미만, 계속 제한 미만으로 유지될 예정 | Deny | Allow | Allow |
| 종량제 연결, 로밍 중이 아님, 데이터 한도 미만, 한도 초과 예정 | Deny | Deny | Allow |
| 종량제 연결, 로밍, 데이터 제한 미만 | Deny | Deny | Allow |
| 종량제 연결, 데이터 제한 초과 이 상태는 사용자가 "Data Sense UI에서 백그라운드 데이터 제한"을 사용하도록 설정한 경우에만 발생합니다. | Deny | Deny | Deny |
파일 업로드
백그라운드 전송을 사용하는 경우 업로드는 작업을 다시 시작하거나 취소하는 데 사용되는 여러 제어 메서드를 노출하는 UploadOperation 으로 존재합니다. 앱 이벤트(예: 일시 중단 또는 종료) 및 연결 변경은 UploadOperation당 시스템에서 자동으로 처리됩니다. 업로드는 앱 일시 중단 기간 동안 계속되거나 앱 종료 이후에도 일시 중지되고 유지됩니다. 또한 CostPolicy 속성을 설정하면 데이터 통신 네트워크가 인터넷 연결에 사용되는 동안 앱이 업로드를 시작할지 여부를 나타냅니다.
다음 예제에서는 기본 업로드의 생성 및 초기화와 이전 앱 세션에서 유지된 작업을 열거하고 다시 도입하는 방법을 안내합니다.
단일 파일 업로드
업로드 만들기는 BackgroundUploader로 시작합니다. 이 클래스는 결과 UploadOperation을 만들기 전에 앱이 업로드를 구성할 수 있도록 하는 메서드를 제공하는 데 사용됩니다. 다음 예제에서는 필요한 Uri 및 StorageFile 개체를 사용하여 이 작업을 수행하는 방법을 보여 줍니다.
업로드의 파일 및 대상 식별
UploadOperation 만들기를 시작하기 전에 먼저 업로드할 위치의 URI와 업로드할 파일을 식별해야 합니다. 다음 예제에서는 uriString 값이 UI 입력의 문자열과 PickSingleFileAsync 작업에서 반환된 StorageFile 개체를 사용하는 파일 값을 사용하여 채워집니다.
function uploadFile() {
var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
filePicker.fileTypeFilter.replaceAll(["*"]);
filePicker.pickSingleFileAsync().then(function (file) {
if (!file) {
printLog("No file selected");
return;
}
var upload = new UploadOp();
var uriString = document.getElementById("serverAddressField").value;
upload.start(uriString, file);
// Store the upload operation in the uploadOps array.
uploadOperations.push(upload);
});
}
업로드 작업 만들기 및 초기화
이전 단계에서 uriString 및 파일 값은 새 업로드 작업을 구성하고 시작하는 데 사용되는 다음 예제 UploadOp의 인스턴스로 전달됩니다. 먼저 uriString 을 구문 분석하여 필요한 Uri 개체를 만듭니다.
다음으로, 제공된 StorageFile (파일)의 속성은 BackgroundUploader 에서 요청 헤더를 채우고 SourceFile 속성을 StorageFile 개체로 설정하는 데 사용됩니다. 그런 다음 SetRequestHeader 메서드를 호출하여 문자열로 제공된 파일 이름과 StorageFile.Name 속성을 삽입합니다.
마지막으로 BackgroundUploader 는 UploadOperation (업로드)을 만듭니다.
function UploadOp() {
var upload = null;
var promise = null;
this.start = function (uriString, file) {
try {
var uri = new Windows.Foundation.Uri(uriString);
var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
// Set a header, so the server can save the file (this is specific to the sample server).
uploader.setRequestHeader("Filename", file.name);
// Create a new upload operation.
upload = uploader.createUpload(uri, file);
// Start the upload and persist the promise to be able to cancel the upload.
promise = upload.startAsync().then(complete, error, progress);
} catch (err) {
displayError(err);
}
};
// On application activation, reassign callbacks for a upload
// operation persisted from previous application state.
this.load = function (loadedUpload) {
try {
upload = loadedUpload;
promise = upload.attachAsync().then(complete, error, progress);
} catch (err) {
displayError(err);
}
};
}
JavaScript promise를 사용하여 정의된 비동기 메서드 호출을 확인합니다. 마지막 예제의 줄을 확인합니다.
promise = upload.startAsync().then(complete, error, progress);
비동기 메서드 호출 뒤에 then 비동기 메서드 호출의 결과가 반환될 때 호출되는 메서드를 나타내는 문이 앱을 통해 정의됩니다. 이 프로그래밍 패턴에 대한 자세한 내용은 Promise를 사용하는 JavaScript의 비동기 프로그래밍을 참조하세요.
여러 파일 업로드
업로드할 파일 및 대상 식별
단일 UploadOperation으로 전송된 여러 파일이 포함된 시나리오에서 프로세스는 일반적으로 필요한 대상 URI 및 로컬 파일 정보를 먼저 제공하여 시작됩니다. 이전 섹션의 예제와 마찬가지로 URI는 최종 사용자가 문자열로 제공하고 FileOpenPicker 를 사용하여 사용자 인터페이스를 통해 파일을 나타내는 기능도 제공할 수 있습니다. 그러나 이 시나리오에서 앱은 UI를 통해 여러 파일을 선택할 수 있도록 PickMultipleFilesAsync 메서드를 대신 호출해야 합니다.
function uploadFiles() {
var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
filePicker.fileTypeFilter.replaceAll(["*"]);
filePicker.pickMultipleFilesAsync().then(function (files) {
if (files === 0) {
printLog("No file selected");
return;
}
var upload = new UploadOperation();
var uriString = document.getElementById("serverAddressField").value;
upload.startMultipart(uriString, files);
// Persist the upload operation in the global array.
uploadOperations.push(upload);
});
}
제공된 매개 변수에 대한 개체 만들기
다음 두 예제에서는 마지막 단계의 끝에서 호출된 단일 예제 메서드 startMultipart에 포함된 코드를 사용합니다. 명령을 위해 BackgroundTransferContentPart 개체의 배열을 만드는 메서드의 코드가 결과 UploadOperation을 만드는 코드에서 분할되었습니다.
먼저 사용자가 제공한 URI 문자열이 Uri로 초기화됩니다. 다음으로, 이 메서드에 전달된 IStorageFile 개체(파일)의 배열이 반복되고 각 개체는 contentParts 배열에 배치되는 새 BackgroundTransferContentPart 개체를 만드는 데 사용됩니다.
upload.startMultipart = function (uriString, files) {
try {
var uri = new Windows.Foundation.Uri(uriString);
var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
var contentParts = [];
files.forEach(function (file, index) {
var part = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart("File" + index, file.name);
part.setFile(file);
contentParts.push(part);
});
다중 파트 업로드 작업 만들기 및 초기화
contentParts 배열이 업로드할 각 IStorageFile을 나타내는 모든 BackgroundTransferContentPart 개체로 채워지므로 URI를 사용하여 CreateUploadAsync를 호출하여 요청이 전송될 위치를 나타낼 준비가 된 것입니다.
// Create a new upload operation.
uploader.createUploadAsync(uri, contentParts).then(function (uploadOperation) {
// Start the upload and persist the promise to be able to cancel the upload.
upload = uploadOperation;
promise = uploadOperation.startAsync().then(complete, error, progress);
});
} catch (err) {
displayError(err);
}
};
중단된 업로드 작업 다시 시작
UploadOperation의 완료 또는 취소 시 연결된 모든 시스템 리소스가 해제됩니다. 그러나 이러한 작업 중 하나가 발생하기 전에 앱이 종료되면 활성 작업이 일시 중지되고 각 작업과 연결된 리소스가 그대로 유지됩니다. 이러한 작업이 열거되어 다음 앱 세션에 다시 도입되지 않으면 완료되지 않으며 디바이스 리소스를 계속 차지합니다.
지속형 작업을 열거하는 함수를 정의하기 전에 반환할 UploadOperation 개체를 포함하는 배열을 만들어야 합니다.
var uploadOperations = [];다음으로 지속형 작업을 열거하고 배열에 저장하는 함수를 정의합니다. 앱 종료를 통해 유지되는 경우 UploadOperation에 콜백을 다시 할당하기 위해 호출된 로드 메서드는 이 섹션의 뒷부분에서 정의한 UploadOp 클래스에 있습니다.
function Windows.Networking.BackgroundTransfer.BackgroundUploader.getCurrentUploadsAsync() { .then(function (uploads) { for (var i = 0; i < uploads.size; i++) { var upload = new UploadOp(); upload.load(uploads[i]); uploadOperations.push(upload); } } };
파일 다운로드
백그라운드 전송을 사용하는 경우 각 다운로드는 작업을 일시 중지, 다시 시작, 다시 시작 및 취소하는 데 사용되는 여러 제어 메서드를 노출하는 DownloadOperation 으로 존재합니다. 앱 이벤트(예: 일시 중단 또는 종료) 및 연결 변경은 DownloadOperation당 시스템에서 자동으로 처리됩니다. 다운로드는 앱 일시 중단 기간 동안 계속되거나 앱 종료 이후에도 일시 중지되고 유지됩니다. 모바일 네트워크 시나리오의 경우 CostPolicy 속성을 설정하면 데이터 통신 네트워크를 인터넷 연결에 사용하는 동안 앱이 다운로드를 시작할지 아니면 계속 다운로드할지 여부를 나타냅니다.
빠르게 완료할 가능성이 있는 작은 리소스를 다운로드하는 경우 백그라운드 전송 대신 HttpClient API를 사용해야 합니다.
다음 예제에서는 기본 다운로드의 생성 및 초기화와 이전 앱 세션에서 유지된 작업을 열거하고 다시 도입하는 방법을 안내합니다.
백그라운드 전송 파일 다운로드 구성 및 시작
다음 예제에서는 URI 및 파일 이름을 나타내는 문자열을 사용하여 요청된 파일을 포함할 Uri 개체 및 StorageFile 을 만드는 방법을 보여 줍니다. 이 예제에서는 새 파일이 미리 정의된 위치에 자동으로 배치됩니다. 또는 FileSavePicker 를 사용하여 사용자가 디바이스에서 파일을 저장할 위치를 나타낼 수 있습니다. 앱 종료를 통해 유지되는 경우 DownloadOperation에 콜백을 다시 할당하기 위해 호출된 로드 메서드는 이 섹션의 뒷부분에 정의된 DownloadOp 클래스에 있습니다.
function DownloadOp() {
var download = null;
var promise = null;
var imageStream = null;
this.start = function (uriString, fileName) {
try {
// Asynchronously create the file in the pictures folder.
Windows.Storage.KnownFolders.picturesLibrary.createFileAsync(fileName, Windows.Storage.CreationCollisionOption.generateUniqueName).done(function (newFile) {
var uri = Windows.Foundation.Uri(uriString);
var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
// Create a new download operation.
download = downloader.createDownload(uri, newFile);
// Start the download and persist the promise to be able to cancel the download.
promise = download.startAsync().then(complete, error, progress);
}, error);
} catch (err) {
displayException(err);
}
};
// On application activation, reassign callbacks for a download
// operation persisted from previous application state.
this.load = function (loadedDownload) {
try {
download = loadedDownload;
printLog("Found download: " + download.guid + " from previous application run.<br\>");
promise = download.attachAsync().then(complete, error, progress);
} catch (err) {
displayException(err);
}
};
}
JavaScript promise를 사용하여 정의된 비동기 메서드 호출을 확인합니다. 이전 코드 예제의 줄 17을 확인합니다.
promise = download.startAsync().then(complete, error, progress);
비동기 메서드 호출 다음에는 비동기 메서드 호출의 결과가 반환될 때 호출되는 메서드를 나타내는 다음 문이 앱을 통해 정의됩니다. 이 프로그래밍 패턴에 대한 자세한 내용은 Promise를 사용하는 JavaScript의 비동기 프로그래밍을 참조하세요.
추가 작업 제어 메서드 추가
추가 DownloadOperation 메서드를 구현하여 제어 수준을 높일 수 있습니다. 예를 들어 위의 예제에 다음 코드를 추가하면 다운로드를 취소하는 기능이 도입됩니다.
// Cancel download.
this.cancel = function () {
try {
if (promise) {
promise.cancel();
promise = null;
printLog("Canceling download: " + download.guid + "<br\>");
if (imageStream) {
imageStream.close();
}
}
else {
printLog("Download " + download.guid + " already canceled.<br\>");
}
} catch (err) {
displayException(err);
}
};
시작 시 지속형 작업 열거
DownloadOperation이 완료되거나 취소되면 연결된 시스템 리소스가 모두 해제됩니다. 그러나 이러한 이벤트 중 하나가 발생하기 전에 앱이 종료되면 다운로드가 일시 중지되고 백그라운드에서 유지됩니다. 다음 예제에서는 지속형 다운로드를 새 앱 세션에 다시 도입하는 방법을 보여 줍니다.
지속형 작업을 열거하는 함수를 정의하기 전에 반환할 DownloadOperation 개체를 포함하는 배열을 만들어야 합니다.
var downloadOps = [];다음으로 지속형 작업을 열거하고 배열에 저장하는 함수를 정의합니다. 지속형 DownloadOperation에 대한 콜백을 다시 할당하기 위해 호출된 로드 메서드는 이 섹션의 뒷부분에서 정의하는 DownloadOp 예제에 있습니다.
// Enumerate outstanding downloads. Windows.Networking.BackgroundTransfer.BackgroundDownloader.getCurrentDownloadsAsync().done(function (downloads) { for (var i = 0; i < downloads.size; i++) { var download = new DownloadOp(); download.load(downloads[i]); downloadOps.push(download); } });이제 채워진 목록을 사용하여 보류 중인 작업을 다시 시작할 수 있습니다.
후처리
Windows 10 새로운 기능은 앱이 실행되지 않는 경우에도 백그라운드 전송이 완료될 때 애플리케이션 코드를 실행하는 기능입니다. 예를 들어 앱은 시작될 때마다 앱이 새 영화를 검색하는 대신 영화 다운로드가 완료된 후 사용 가능한 영화 목록을 업데이트하려고 할 수 있습니다. 또는 앱이 다른 서버 또는 포트를 사용하여 다시 시도하여 실패한 파일 전송을 처리하려고 할 수 있습니다. 성공 및 실패한 전송 모두에 대해 사후 처리가 호출되므로 이를 사용하여 사용자 지정 오류 처리 및 재시도 논리를 구현할 수 있습니다.
후처리는 기존 백그라운드 작업 인프라를 사용합니다. 전송을 시작하기 전에 백그라운드 작업을 만들고 해당 작업을 전송에 연결합니다. 그런 다음 전송이 백그라운드에서 실행되고 완료되면 백그라운드 작업이 호출되어 사후 처리를 수행합니다.
사후 처리에서는 새 클래스 인 BackgroundTransferCompletionGroup을 사용합니다. 이 클래스는 백그라운드 전송을 함께 그룹화할 수 있다는 측면에서 기존 BackgroundTransferGroup 과 유사하지만 BackgroundTransferCompletionGroup 은 전송이 완료될 때 실행할 백그라운드 작업을 지정하는 기능을 추가합니다.
다음과 같이 사후 처리를 사용하여 백그라운드 전송을 시작합니다.
- BackgroundTransferCompletionGroup 개체를 만듭니다. 그런 다음 BackgroundTaskBuilder 개체를 만듭니다. 작성기 개체의 Trigger 속성을 완료 그룹 개체로 설정하고, 작성기의 TaskEntryPoint 속성을 전송 완료 시 실행해야 하는 백그라운드 작업의 진입점으로 설정합니다. 마지막으로 BackgroundTaskBuilder.Register 메서드를 호출하여 백그라운드 작업을 등록합니다. 많은 완료 그룹은 하나의 백그라운드 작업 진입점을 공유할 수 있지만 백그라운드 작업 등록당 하나의 완료 그룹만 가질 수 있습니다.
var completionGroup = new BackgroundTransferCompletionGroup();
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();
builder.Name = "MyDownloadProcessingTask";
builder.SetTrigger(completionGroup.Trigger);
builder.TaskEntryPoint = "Tasks.BackgroundDownloadProcessingTask";
BackgroundTaskRegistration downloadProcessingTask = builder.Register();
- 다음으로 백그라운드 전송을 완료 그룹과 연결합니다. 모든 전송이 만들어지면 완료 그룹을 사용하도록 설정합니다.
BackgroundDownloader downloader = new BackgroundDownloader(completionGroup);
DownloadOperation download = downloader.CreateDownload(uri, file);
Task<DownloadOperation> startTask = download.StartAsync().AsTask();
// App still sees the normal completion path
startTask.ContinueWith(ForegroundCompletionHandler);
// Do not enable the CompletionGroup until after all downloads are created.
downloader.CompletionGroup.Enable();
- 백그라운드 작업의 코드는 트리거 세부 정보에서 작업 목록을 추출하고 코드는 각 작업에 대한 세부 정보를 검사하고 각 작업에 대해 적절한 사후 처리를 수행할 수 있습니다.
public class BackgroundDownloadProcessingTask : IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
var details = (BackgroundTransferCompletionGroupTriggerDetails)taskInstance.TriggerDetails;
IReadOnlyList<DownloadOperation> downloads = details.Downloads;
// Do post-processing on each finished operation in the list of downloads
}
}
사후 처리 작업은 일반적인 백그라운드 작업입니다. 모든 백그라운드 작업의 풀에 속하며 모든 백그라운드 작업과 동일한 리소스 관리 정책이 적용됩니다.
또한 사후 처리는 포그라운드 완료 처리기를 대체하지 않습니다. 앱이 포그라운드 완료 처리기를 정의하고 파일 전송이 완료될 때 앱이 실행되는 경우 포그라운드 완료 처리기와 백그라운드 완료 처리기가 모두 호출됩니다. 포그라운드 및 백그라운드 작업이 호출되는 순서는 보장되지 않습니다. 둘 다 정의하는 경우 두 작업이 제대로 작동하고 동시에 실행되는 경우 서로 간섭하지 않도록 해야 합니다.
요청 시간 제한
고려해야 할 두 가지 기본 연결 시간 제한 시나리오가 있습니다.
전송에 대한 새 연결을 설정할 때 연결 요청이 5분 내에 설정되지 않으면 중단됩니다.
연결이 설정되면 2분 이내에 응답을 받지 못한 HTTP 요청 메시지가 중단됩니다.
참고 두 시나리오 모두 인터넷에 연결되어 있다고 가정할 때 백그라운드 전송은 요청을 최대 3번 자동으로 다시 시도합니다. 인터넷 연결이 감지되지 않으면 추가 요청은 연결이 감지될 때까지 대기합니다.
디버깅 지침
Microsoft Visual Studio 디버깅 세션을 중지하는 것은 앱을 닫는 것과 비슷합니다. PUT 업로드가 일시 중지되고 POST 업로드가 종료됩니다. 디버깅하는 동안에도 앱은 지속형 업로드를 열거한 다음 다시 시작하거나 취소해야 합니다. 예를 들어 해당 디버그 세션에 대한 이전 작업에 관심이 없는 경우 앱 시작 시 앱이 열거된 지속형 업로드 작업을 취소할 수 있습니다.
디버그 세션 중에 앱 시작 시 다운로드/업로드를 열거하는 동안 해당 디버그 세션에 대한 이전 작업에 관심이 없는 경우 앱을 취소할 수 있습니다. 앱 매니페스트 변경과 같은 Visual Studio 프로젝트 업데이트가 있고 앱이 제거되고 다시 배포된 경우 GetCurrentUploadsAsync는 이전 앱 배포를 사용하여 만든 작업을 열거할 수 없습니다.
개발 중에 백그라운드 전송을 사용하는 경우 활성 및 완료된 전송 작업의 내부 캐시가 동기화되지 않을 수 있는 상황이 발생할 수 있습니다. 이로 인해 새 전송 작업을 시작하거나 기존 작업 및 BackgroundTransferGroup 개체와 상호 작용할 수 없게 될 수 있습니다. 경우에 따라 기존 작업과 상호 작용하려고 시도하면 충돌이 트리거될 수 있습니다. 이 결과는 TransferBehavior 속성이 병렬로 설정된 경우에 발생할 수 있습니다. 이 문제는 개발 중에 특정 시나리오에서만 발생하며 앱의 최종 사용자에게는 적용되지 않습니다.
Visual Studio 사용하는 네 가지 시나리오에서 이 문제가 발생할 수 있습니다.
- 기존 프로젝트와 앱 이름이 같지만 다른 언어(예: C++에서 C#)로 새 프로젝트를 만듭니다.
- 기존 프로젝트에서 대상 아키텍처(예: x86에서 x64로)를 변경합니다.
- 기존 프로젝트에서 문화권(예: 중립에서 en-US)을 변경합니다.
- 기존 프로젝트의 패키지 매니페스트(예: 엔터프라이즈 인증 추가)에서 기능을 추가하거나 제거합니다.
기능을 추가하거나 제거하는 매니페스트 업데이트를 비롯한 일반 앱 서비스가 앱의 최종 사용자 배포 시 이 문제를 트리거하지 않습니다. 이 문제를 해결하려면 앱의 모든 버전을 완전히 제거하고 새 언어, 아키텍처, 문화권 또는 기능을 사용하여 다시 배포합니다. 이 작업은 시작 화면 또는 PowerShell 및 Remove-AppxPackage cmdlet을 사용하여 수행할 수 있습니다.
Windows.Networking.BackgroundTransfer의 예외
Windows.Foundation.Uri 개체의 생성자에 잘못된 URI(Uniform Resource Identifier) 문자열이 전달되면 예외가 발생합니다.
.NET:Windows. Foundation.Uri 형식은 C# 및 VB에서 System.Uri로 표시됩니다.
C# 및 Visual Basic .NET 4.5의 System.Uri 클래스와 System.Uri.TryCreate 메서드 중 하나를 사용하여 URI가 생성되기 전에 앱 사용자로부터 받은 문자열을 테스트하여 이 오류를 방지할 수 있습니다.
C++에서는 문자열을 URI로 구문 분석하는 메서드가 없습니다. 앱이 Windows.Foundation.Uri에 대해 사용자로부터 입력을 받는 경우, 생성자를 try/catch 블록 내에서 호출해야 합니다. 예외가 발생하면 앱은 사용자에게 알린 후 새 호스트 이름을 요청할 수 있습니다.
Windows.Networking.backgroundTransfer 네임스페이스에는 편리한 도우미 메서드가 있으며, 오류 처리를 위해 Windows.Networking.Sockets 네임스페이스의 열거형을 사용합니다. 이는 앱에서 특정 네트워크 예외를 다르게 처리하는 데 유용할 수 있습니다.
Windows 비동기 메서드에서 오류가 발생했습니다. Networking.backgroundTransfer 네임스페이스는 HRESULT 값으로 반환됩니다. BackgroundTransferError.GetStatus 메서드는 네트워크 오류를 백그라운드 전송 작업에서 WebErrorStatus 열거형 값으로 변환하는 데 사용됩니다. 대부분의 WebErrorStatus 열거형 값은 네이티브 HTTP 또는 FTP 클라이언트 작업에서 반환된 오류에 해당합니다. 앱은 특정 WebErrorStatus 열거형 값을 필터링하여 예외의 원인에 따라 앱 동작을 수정할 수 있습니다.
매개 변수 유효성 검사 오류의 경우 앱은 예외의 HRESULT 를 사용하여 예외를 발생시킨 오류에 대한 자세한 정보를 알아볼 수도 있습니다. 가능한 HRESULT 값은 Winerror.h 헤더 파일에 나열됩니다. 대부분의 매개 변수 유효성 검사 오류의 경우 반환된 HRESULT 는 E_INVALIDARG.
중요 API
Windows developer