バックグラウンド転送Background transfers

ネットワーク経由でファイルを確実にコピーするには、バックグラウンド転送 API を使います。Use the background transfer API to copy files reliably over the network. バックグラウンド転送 API には、アプリの一時停止中はバックグラウンドで実行され、アプリの終了後も実行が続行される高度なアップロード機能とダウンロード機能があります。The background transfer API provides advanced upload and download features that run in the background during app suspension and persist beyond app termination. この API は、ネットワークの状態を監視し、接続が失われたときに転送の中断と再開を自動的に実行します。転送ではデータ センサーとバッテリー セーバーにも対応し、ダウンロード アクティビティは現在の接続とデバイスのバッテリー状態に基づいて調整されます。The API monitors network status and automatically suspends and resumes transfers when connectivity is lost, and transfers are also Data Sense-aware and Battery Sense-aware, meaning that download activity adjusts based on your current connectivity and device battery status. この API は、アップロード HTTP(S) を使った大きなファイルのアップロードとダウンロードに適しています。The API is ideal for uploading and downloading large files using HTTP(S). FTP もサポートされますが、その対象はダウンロードのみです。FTP is also supported, but only for downloads.

バックグラウンド転送はアプリの呼び出しとは別に実行され、主にビデオ、音楽、サイズの大きい画像などのリソースの長期の転送操作を目的としています。Background Transfer runs separately from the calling app and is primarily designed for long-term transfer operations for resources like video, music, and large images. これらのシナリオでは、アプリが一時停止状態でもダウンロードが続行されるため、バックグラウンド転送の使用が不可欠です。For these scenarios, using Background Transfer is essential because downloads continue to progress even when the app is suspended.

すぐに完了する可能性がある小さいリソースをダウンロードする場合は、バックグラウンド転送ではなく HttpClient API を使ってください。If you are downloading small resources that are likely to complete quickly, you should use HttpClient APIs instead of Background Transfer.

Windows.Networking.BackgroundTransfer を使うUsing Windows.Networking.BackgroundTransfer

バックグラウンド転送機能はどのように動作するかHow does the Background Transfer feature work?

アプリがバックグラウンド転送を使って転送を開始するときは、BackgroundDownloader または BackgroundUploader クラス オブジェクトを使って要求が構成され初期化されます。When an app uses Background Transfer to initiate a transfer, the request is configured and initialized using BackgroundDownloader or BackgroundUploader class objects. それぞれの転送操作は、呼び出し元アプリとは別にシステムによって個別に処理されます。Each transfer operation is handled individually by the system and separate from the calling app. 進行情報はアプリの UI でユーザーに状況を示す場合に利用することができ、アプリで一時停止、再開、キャンセルしたり、転送中にデータを読み取ったりすることができます。Progress information is available if you want to give status to the user in your app's UI, and your app can pause, resume, cancel, or even read from the data while the transfer is occurring. システムによって転送が処理される方法により、スマートな電力消費が実現し、アプリの中断や終了、突然のネットワーク ステータス変化などのイベントが接続アプリで発生したときに起こる可能性のある問題を回避できます。The way transfers are handled by the system promotes smart power usage and prevents problems that can arise when a connected app encounters events such as app suspension, termination, or sudden network status changes.

注意

アプリごとのリソースの制約により、常にアプリに 200 を超える転送 (DownloadOperations および UploadOperations) を含めてはなりません。Due to per-app resource constraints, an app should not have more than 200 transfers (DownloadOperations + UploadOperations) at any given time. この制限を超過すると、アプリの転送キューが回復不能な状態になる可能性があります。Exceeding that limit may leave the app’s transfer queue in an unrecoverable state.

アプリケーションの起動時に、既存のすべての DownloadOperation および UploadOperation オブジェクトに対して AttachAsync を呼び出す必要があります。When an application is launched, it must call AttachAsync on all existing DownloadOperation and UploadOperation objects. これを行わないと、すでに完了している転送のリークが発生し、最終的にバックグラウンド転送機能が使用できなくなります。Not doing this will cause the leak of already-completed transfers and will eventually render your use of the Background Transfer feature useless.

バックグラウンド転送での認証されたファイル要求の実行Performing authenticated file requests with Background Transfer

バックグラウンド転送では、基本サーバーとプロキシの資格情報、Cookie をサポートするメソッドが用意されており、それぞれの転送操作で (SetRequestHeader を介して) カスタム HTTP ヘッダーを使うこともできます。Background Transfer provides methods that support basic server and proxy credentials, cookies, and the use of custom HTTP headers (via SetRequestHeader) for each transfer operation.

この機能ではネットワーク ステータスの変化や予期しないシャットダウンにどのように対応するかHow does this feature adapt to network status changes or unexpected shutdowns?

バックグラウンド転送機能により、ネットワークの状態が変化したときに各転送操作に対して一貫性のあるエクスペリエンスが保たれます。これは、接続 機能によって提供される接続とキャリアのデータ プラン ステータスの情報をインテリジェントに利用しています。The Background Transfer feature maintains a consistent experience for each transfer operation when network status changes occur, by intelligently leveraging connectivity and carrier data-plan status information provided by the Connectivity feature. さまざまなネットワーク シナリオでの動作を定義するために、アプリは、BackgroundTransferCostPolicy によって定義された値を使って、各転送操作のコスト ポリシーを設定します。To define behavior for different network scenarios, an app sets a cost policy for each operation using values defined by BackgroundTransferCostPolicy.

たとえば、操作に対して定義されたコスト ポリシーで、デバイスが従量制課金接続を使っているときに操作を自動的に一時停止する必要があることを示すことができます。For example, the cost policy defined for an operation can indicate that the operation should be paused automatically when the device is using a metered network. "制限のない" ネットワークへの接続が確立されたときには、転送が自動的に再開されます。The transfer is then automatically resumed (or restarted) when a connection to an "unrestricted" network has been established. コストによってネットワークがどのように定義されるかについては、「NetworkCostType」をご覧ください。For more information on how networks are defined by cost, see NetworkCostType.

バックグラウンド転送機能にはネットワーク ステータスの変化に対応する独自のメカニズムがありますが、ネットワーク接続されたアプリには他にも一般的な接続の考慮事項があります。While the Background Transfer feature has its own mechanisms for handling network status changes, there are other general connectivity considerations for network-connected apps. 詳しくは、「利用できるネットワーク接続情報の活用」をご覧ください。Read Leveraging available network connection information for additional info.

注:    モバイル デバイスで実行されるアプリでは、接続の種類、ローミング状態、ユーザーのデータ通信プランに基づいて転送されるデータの量を、ユーザーが監視および制限できる機能が用意されています。Note  For apps running on mobile devices, there are features that allow the user to monitor and restrict the amount of data that is transferred based on the type of connection, roaming status, and the user's data plan. このため、BackgroundTransferCostPolicy が転送が継続中であることを示す場合でも、電話でバックグラウンド転送が一時停止される可能性があります。Because of this, background transfers may be paused on the phone even when the BackgroundTransferCostPolicy indicates that the transfer should proceed.

次の表に、電話の現在の状態に応じて、BackgroundTransferCostPolicy の各値に対して、電話でバックグラウンド転送が許可されるかどうかを示します。The following table indicates when background transfers are allowed on the phone for each BackgroundTransferCostPolicy value, given the current state of the phone. ConnectionCost クラスを使って、電話の現在の状態を判断できます。You can use the ConnectionCost class to determine the phone's current state.

デバイスの状態Device State UnrestrictedOnlyUnrestrictedOnly DefaultDefault 常にAlways
WiFi 接続Connected to WiFi 許可Allow 許可Allow 許可Allow
従量制課金接続、ローミング時以外、データ制限未満、制限内にとどまる見込みMetered Connection, not roaming, under data limit, on track to stay under limit 拒否Deny 許可Allow 許可Allow
従量制課金接続、ローミング時以外、データ制限未満、制限を超過する見込みMetered Connection, not roaming, under data limit, on track to exceed limit 拒否Deny 拒否Deny 許可Allow
従量制課金接続、ローミング時、データ制限未満Metered Connection, roaming, under data limit 拒否Deny 拒否Deny 許可Allow
従量制課金接続、データ制限超過Metered Connection, over data limit. この状態は、ユーザーが Data Sense UI で [バックグラウンドでのデータ通信を制限する] を有効にしている場合にのみ発生します。This state only occurs when the user enables "Restrict background data in the Data Sense UI. 拒否Deny 拒否Deny 拒否Deny

ファイルのアップロードUploading files

バックグラウンド転送を使う場合、アップロードは UploadOperation として存在し、操作の再起動や取り消しに使われる多くの制御メソッドを公開します。When using Background Transfer an upload exists as an UploadOperation that exposes a number of control methods that are used to restart or cancel the operation. アプリのイベント (一時停止、終了など) や接続の変更は、UploadOperation を通じてシステムによって自動的に処理されます。アップロードは、アプリの一時停止中も続行し、アプリの終了以降は一時停止して保持されます。App events (e.g. suspension or termination) and connectivity changes are handled automatically by the system per UploadOperation; uploads will continue during app suspension periods or pause and persist beyond app termination. また、CostPolicy プロパティを設定することで、従量制課金接続がインターネット接続のために使われている間もアプリがアップロードを開始するかどうかを指定します。Additionally, setting the CostPolicy property will indicate whether or not your app will start uploads while a metered network is being used for Internet connectivity.

以下に、基本的なアップロードを作成および初期化する例と、前のアプリ セッションから続いている操作を列挙および再び取り込む例を示します。The following examples will walk you through the creation and initialization of a basic upload and how to enumerate and reintroduce operations persisted from a previous app session.

1 つのファイルのアップロードUploading a single file

アップロードの作成は、BackgroundUploader から始めます。The creation of an upload begins with BackgroundUploader. このクラスは、アプリで UploadOperation を作成する前に、そのアップロードを構成できるようにするメソッドを提供するために使われます。This class is used to provide the methods that enable your app to configure the upload before creating the resultant UploadOperation. 次の例は、必要な Uri オブジェクトと StorageFile オブジェクトを使ってこれを行う方法を示しています。The following example shows how to do this with the required Uri and StorageFile objects.

アップロードするファイルと送信先の特定Identify the file and destination for the upload

UploadOperation の作成を始める前に、アップロード先となる場所の URI とアップロードされるファイルを識別する必要があります。Before we can begin with the creation of an UploadOperation, we first need to identify the URI of the location to upload to, and the file that will be uploaded. 次の例では、UI 入力からの文字列を使って uriString の値が設定され、PickSingleFileAsync 操作で返される StorageFile オブジェクトを使って file の値が設定されます。In the following example, the uriString value is populated using a string from UI input, and the file value using the StorageFile object returned by a PickSingleFileAsync operation.

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);
    });
}

アップロード操作の作成と初期化Create and initialize the upload operation

前の手順では、uriStringfile の値が次に示す例の UploadOp のインスタンスに渡されました。これらの値は、新しいアップロード操作を構成し開始するために使われます。In the previous step the uriString and file values are passed to an instance of our next example, UploadOp, where they are used to configure and start the new upload operation. まず、uriString が解析されて、要求された Uri オブジェクトが作成されます。First, uriString is parsed to create the required Uri object.

そして、与えられた StorageFile (file) のプロパティが BackgroundUploader で使われて要求ヘッダーが設定され、SourceFile プロパティに StorageFile オブジェクトが設定されます。Next, the properties of the provided StorageFile (file) are used by BackgroundUploader to populate the request header and set the SourceFile property with the StorageFile object. 次に、SetRequestHeader メソッドが呼び出され、文字列として提供されたファイル名と StorageFile.Name プロパティが挿入されます。The SetRequestHeader method is then called to insert the file name, provided as a string, and the StorageFile.Name property.

最後に、BackgroundUploader によって UploadOperation (upload) が作成されます。Finally, BackgroundUploader creates the UploadOperation (upload).

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 を使って定義した非同期メソッドの呼び出しに注意してください。Note the asynchronous method calls defined using JavaScript promises. 最後の例には次の行があります。Looking at a line from the last example:

promise = upload.startAsync().then(complete, error, progress);

非同期メソッドの後に then ステートメントが続いています。このステートメントでは、非同期メソッドの呼び出しの結果が返されたときに呼び出される、アプリで定義されたメソッドを指定しています。The async method call is followed by a then statement which indicates methods, defined by the app, that are called when a result from the async method call is returned. このプログラミング パターンについて詳しくは、「プロミスを使った JavaScript での非同期プログラミング」をご覧ください。For more information on this programming pattern, see Asynchronous programming in JavaScript using promises.

複数のファイルのアップロードUploading multiple files

アップロードするファイルと送信先の特定Identify the files and destination for the upload

単一の UploadOperation で複数のファイルを転送するシナリオでは、処理は通常どおり、最初に必要なアップロード先 URI とローカル ファイルの情報を指定することから始まります。In a scenario involving multiple files transferred with a single UploadOperation, the process begins as it usually does by first providing the required destination URI and local file information. 前のセクションの例と同様に、URI はエンド ユーザーが文字列で指定します。また、FileOpenPicker を使って、ユーザー インターフェイスからファイルを指定する機能も提供できます。Similar to the example in the previous section, the URI is provided as a string by the end-user and FileOpenPicker can be used to provide the ability to indicate files through the user interface as well. ただし、このシナリオでは、アプリで代わりに PickMultipleFilesAsync メソッドを呼び出して、UI から複数のファイルを選ぶことができるようにする必要があります。However, in this scenario the app should instead call the PickMultipleFilesAsync method to enable the selection of multiple files through the UI.

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);
       });
    }

指定されたパラメーターに基づくオブジェクトの作成Create objects for the provided parameters

次の 2 つの例では、前の手順の最後に呼び出された単一のメソッド例 startMultipart に含まれているコードを使っています。The next two examples use code contained in a single example method, startMultipart, which was called at the end of the last step. わかりやすくするために、BackgroundTransferContentPart オブジェクトの配列を作るメソッドのコードは、結果の UploadOperation を作るコードから分割されています。For the purpose of instruction the code in the method that creates an array of BackgroundTransferContentPart objects has been split from the code that creates the resultant UploadOperation.

最初に、ユーザーが指定した URI 文字列を Uri として初期化します。First, the URI string provided by the user is initialized as a Uri. 次に、このメソッドに渡された IStorageFile オブジェクト (files) の配列を反復処理し、配列内の各オブジェクトを使って新しい BackgroundTransferContentPart オブジェクトを作り、そのオブジェクトを contentParts 配列に配置します。Next, the array of IStorageFile objects (files) passed to this method is iterated through, each object is used to create a new BackgroundTransferContentPart object which is then placed in the contentParts array.

    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);
            });

マルチパート アップロード操作の作成と初期化Create and initialize the multi-part upload operation

contentParts 配列には、アップロード用の各 IStorageFile を表す BackgroundTransferContentPart オブジェクトがすべて含まれているため、要求の送信先を示す Uri を使って CreateUploadAsync を呼び出すことができます。With our contentParts array populated with all of the BackgroundTransferContentPart objects representing each IStorageFile for upload, we are ready to call CreateUploadAsync using the Uri to indicate where the request will be sent.

        // 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);
         }
     };

中断されたアップロード操作の再開Restarting interrupted upload operations

UploadOperation が完了するか取り消されると、関連するシステム リソースがすべて解放されます。On completion or cancellation of an UploadOperation, any associated system resources are released. ただし、これらのイベントのどちらかが発生する前にアプリが終了した場合、アクティブな操作は一時停止され、それぞれに関連付けられているリソースは占有されたままになります。However, if your app is terminated before either of these things can occur, any active operations are paused and the resources associated with each remain occupied. これらの操作が列挙されずに次のアプリ セッションに再び取り込まれると、それらの操作は完了せず、デバイス リソースを占有したままとなります。If these operations are not enumerated and re-introduced to the next app session, they will not be completed and will continue to occupy device resources.

  1. 持続している操作を列挙する関数を定義する前に、返される UploadOperation オブジェクトを格納する配列を作成する必要があります。Before defining the function that enumerates persisted operations, we need to create an array that will contain the UploadOperation objects that it will return:

    var uploadOperations = [];
    
  2. 次に、持続している操作を列挙してそれらを配列に格納する関数を定義します。Next we define the function that enumerates persisted operations and stores them in our array. UploadOperation に対するコールバックを再び割り当てるために呼び出される load メソッドは、アプリの終了後も持続する場合、このセクションでこの後定義する UploadOp クラス内にあることに注意してください。Note that the load method called to re-assign callbacks to the UploadOperation, should it persist through app termination, is in the UploadOp class we define later in this section.

    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);
            }
        }
    };
    

ファイルのダウンロードDownloading files

バックグラウンド転送を使う場合、各ダウンロードは DownloadOperation として存在し、操作の一時停止、再開、再起動、取り消しに使われる多くの制御メソッドを公開します。When using Background Transfer, each download exists as a DownloadOperation that exposes a number of control methods used to pause, resume, restart, and cancel the operation. アプリのイベント (一時停止、終了など) や接続の変更は、DownloadOperation を通じてシステムによって自動的に処理されます。ダウンロードは、アプリの一時停止中も続行し、アプリの終了以降は一時停止して保持されます。App events (e.g. suspension or termination) and connectivity changes are handled automatically by the system per DownloadOperation; downloads will continue during app suspension periods or pause and persist beyond app termination. モバイル ネットワーク シナリオの場合、CostPolicy プロパティを設定することで、従量制課金接続がインターネット接続のために使われている間もアプリがダウンロードを開始または続行するかどうかを指定します。For mobile network scenarios, setting the CostPolicy property will indicate whether or not your app will begin or continue downloads while a metered network is being used for Internet connectivity.

すぐに完了する可能性がある小さいリソースをダウンロードする場合は、バックグラウンド転送ではなく HttpClient API を使ってください。If you are downloading small resources that are likely to complete quickly, you should use HttpClient APIs instead of Background Transfer.

以下に、基本的なダウンロードを作成および初期化する例と、前のアプリ セッションから続いている操作を列挙および再び取り込む例を示します。The following examples will walk you through the creation and initialization of a basic download, and how to enumerate and reintroduce operations persisted from a previous app session.

バックグラウンド転送によるファイルのダウンロードを構成して開始するConfigure and start a Background Transfer file download

URI とファイル名を表す文字列を使って、Uri オブジェクトと要求されたファイルを格納する StorageFile とを作成する方法を次の例で示します。The following example demonstrates how strings representing a URI and a file name can be used to create a Uri object and the StorageFile that will contain the requested file. この例では、新しいファイルが定義済みの場所に自動的に配置されます。In this example, the new file is automatically placed in a pre-defined location. または、FileSavePicker を使ってユーザーがファイルを保存するデバイスの場所を指定できるようになります。Alternatively, FileSavePicker can be used allow users to indicate where to save the file on the device. DownloadOperation に対するコールバックを再び割り当てるために呼び出される load メソッドは、アプリの終了以降も持続する場合、このセクションでこの後定義する DownloadOp クラス内にあることに注意してください。Note that the load method called to re-assign callbacks to the DownloadOperation, should it persist through app termination, is in the DownloadOp class defined later in this section.

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 を使って定義した非同期メソッドの呼び出しに注意してください。Note the asynchronous method calls defined using JavaScript promises. 前のコード例の 17 行目には次のコードがあります。Looking at line 17 from the previous code example:

promise = download.startAsync().then(complete, error, progress);

非同期メソッドの後に then ステートメントが続いています。このステートメントでは、非同期メソッドの呼び出しの結果が返されたときに呼び出される、アプリで定義されたメソッドを指定しています。The async method call is followed by a then statement which indicates methods, defined by the app, that are called when a result from the async method call is returned. このプログラミング パターンについて詳しくは、「プロミスを使った JavaScript での非同期プログラミング」をご覧ください。For more information on this programming pattern, see Asynchronous programming in JavaScript using promises.

その他の操作制御メソッドの追加Adding additional operation control methods

追加の DownloadOperation メソッドを実装することによって、制御のレベルを高めることができます。The level of control can be increased by implementing additional DownloadOperation methods. 上の例に次のコードを追加すると、ダウンロードをキャンセルすることができるようになります。For example, adding the following code to the example above will introduce the ability to cancel the download.

// 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);
    }
};

持続している操作の起動時の列挙Enumerating persisted operations at start-up

DownloadOperation が完了するか取り消されると、関連するシステム リソースがすべて解放されます。On completion or cancellation of a DownloadOperation, any associated system resources are released. ただし、これらのイベントのどちらかが発生する前にアプリが終了した場合、ダウンロードは一時停止され、バックグラウンドで保持されます。However, if your app is terminated before either of these events occur, downloads will pause and persist in the background. 以下の例は、持続しているダウンロードを新しいアプリ セッションに再び取り込む方法を示しています。The following examples demonstrate how to re-introduce persisted downloads into a new app session.

  1. 持続している操作を列挙する関数を定義する前に、返される DownloadOperation オブジェクトを格納する配列を作成する必要があります。Before defining the function that enumerates persisted operations, we need to create an array that will contain the DownloadOperation objects that it will return:

    var downloadOps = [];
    
  2. 次に、持続している操作を列挙してそれらを配列に格納する関数を定義します。Next we define the function that enumerates persisted operations and stores them in our array. 持続している DownloadOperation に対するコールバックを再び割り当てるために呼び出される load メソッドは、このセクションでこの後定義する DownloadOp の例に含まれていることに注意してください。Note that the load method called to re-assign callbacks for a persisted DownloadOperation is in the DownloadOp example we define later in this section.

    // 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);
        }
    });
    
  3. これで、返された値の一覧を使って、保留中の操作を再開できます。You can now use the populated list to restart pending operations.

後処理Post-processing

Windows 10 の新機能は、アプリが実行されていない場合でも、バックグラウンド転送の完了時にアプリケーション コードを実行できる機能です。A new feature in Windows 10 is the ability to run application code at the completion of a background transfer even when the app is not running. たとえば、アプリが開始されるたびに新しいムービーをスキャンするのではなく、ムービーのダウンロードが完了した後で利用可能な映画の一覧を更新できます。For example, your app might want to update a list of available movies after a movie has finished downloading, rather than have your app scan for new movies every time it starts. または、アプリでファイル転送が失敗した場合に、別のサーバーまたはポートを使ってもう一度転送し直すことができます。Or your app might want to handle a failed file transfer by trying again using a different server or port. 後処理は成功した転送と失敗した転送の両方で呼び出されるため、これを使って、カスタム エラー処理と再試行ロジックを実装できます。Post-processing is invoked for both successful and failed transfers, so you can use it to implement custom error-handling and retry logic.

後処理では、既存のバックグラウンド タスク インフラストラクチャを使います。Postprocessing uses the existing background task infrastructure. 転送を開始する前に、バックグラウンド タスクを作成して転送に関連付けます。You create a background task and associate it with your transfers before you start the transfers. 転送はバックグラウンドで実行され、完了時にバックグラウンド タスクが呼び出されて後処理が実行されます。The transfers are then executed in the background, and when they are complete, your background task is called to perform post-processing.

後処理では、BackgroundTransferCompletionGroup という新しいクラスを使います。Post-processing uses a new class, BackgroundTransferCompletionGroup. このクラスは、バックグラウンド タスクをグループ化できるという点で既存の BackgroundTransferGroup に似ていますが、BackgroundTransferCompletionGroup には、転送の完了時に実行するバックグラウンド タスクを指定できる機能が追加されています。This class is similar to the existing BackgroundTransferGroup in that it allows you to group background transfers together, but BackgroundTransferCompletionGroup adds the ability to designate a background task to be run when the transfer is complete.

後処理があるバックグラウンド転送は、次のように開始します。You initiate a background transfer with post-processing as follows.

  1. BackgroundTransferCompletionGroup オブジェクトを作成します。Create a BackgroundTransferCompletionGroup object. 続けて、BackgroundTaskBuilder オブジェクトを作成します。Then, create a BackgroundTaskBuilder object. ビルダー オブジェクトの Trigger プロパティを完了グループ オブジェクトに設定し、ビルダーの TaskEntryPoint プロパティを、転送完了時に実行する必要があるバックグラウンド タスクのエントリ ポイントに設定します。Set the Trigger property of the builder object to the completion group object, and the TaskEntryPoint property of the builder to the entry point of the background task that should execute on transfer completion. 最後に、BackgroundTaskBuilder.Register メソッドを呼び出してバックグラウンド タスクを登録します。Finally, call the BackgroundTaskBuilder.Register method to register your background task. 複数の完了グループで 1 つのバックグラウンド タスクのエントリ ポイントを共有できますが、バックグラウンド タスクの登録では 1 つの完了グループのみ指定できることに注意してください。Note that many completion groups can share one background task entry point, but you can have only one completion group per background task registration.
var completionGroup = new BackgroundTransferCompletionGroup();
BackgroundTaskBuilder builder = new BackgroundTaskBuilder();

builder.Name = "MyDownloadProcessingTask";
builder.SetTrigger(completionGroup.Trigger);
builder.TaskEntryPoint = "Tasks.BackgroundDownloadProcessingTask";

BackgroundTaskRegistration downloadProcessingTask = builder.Register();
  1. 次に、バックグラウンド転送を完了グループに関連付けます。Next you associate background transfers with the completion group. すべての転送を作成したら、完了グループを有効にします。Once all transfers are created, enable the completion group.
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.CompletinGroup.Enable();
  1. バックグラウンド タスク内のコードで、トリガーの詳細情報から操作の一覧を抽出した後、各操作の詳細を検査し、操作ごとに適切な後処理を実行できます。The code in the background task extracts the list of operations from the trigger details, and your code can then inspect the details for each operation and perform appropriate post-processing for each operation.
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
    }
}

後処理タスクは、通常のバックグラウンド タスクです。The post-processing task is a regular background task. それはすべてのバックグラウンド タスクのプールの一部であり、すべてのバックグラウンド タスクと同じリソース管理ポリシーが適用されます。It is part of the pool of all background tasks, and it is subject to the same resource management policy as all background tasks.

後処理はフォアグラウンド完了ハンドラーに代わるものではないことにも注意してください。Also, note that post-processing does not replace foreground completion handlers. アプリにフォアグラウンド完了ハンドラーが定義されているときに、ファイル転送の完了時にアプリが実行されている場合は、フォアグラウンド完了ハンドラーとバックグラウンド完了ハンドラーの両方が呼び出されます。If your app defines a foreground completion handler, and your app is running when the file transfer completes, then both your foreground completion handler and your background completion handler will be called. フォアグラウンド タスクとバックグラウンド タスクが呼び出される順序は保証されません。The order in which foreground and background tasks are called is not guaranteed. 両方を定義する場合は、2 つのタスクが正常に動作し、同時に実行されても相互に干渉しないことを確認する必要があります。If you define both, you should ensure that the two tasks will work properly and not interfere with each other if they are running concurrently.

要求のタイムアウトRequest timeouts

次の 2 つの主要接続タイムアウト シナリオを考慮する必要があります。There are two primary connection timeout scenarios to take into consideration:

  • 転送のために新しい接続を確立する場合、5 分以内に接続が確立しないと、接続要求は中止されます。When establishing a new connection for a transfer, the connection request is aborted if it is not established within five minutes.

  • 接続が確立された後、2 分以内で応答を受け取らなかった HTTP 要求メッセージは中止されます。After a connection has been established, an HTTP request message that has not received a response within two minutes is aborted.

注:    どちらのシナリオにおいても、バックグラウンド転送はインターネット接続があることを前提に、最高 3 回まで自動的に要求を再試行します。Note  In either scenario, assuming there is Internet connectivity, Background Transfer will retry a request up to three times automatically. インターネット接続が検出されないと、検出されるまで別の要求は待機します。In the event Internet connectivity is not detected, additional requests will wait until it is.

デバッグのガイダンスDebugging guidance

Microsoft Visual Studio でデバッグ セッションを停止することは、アプリを閉じることに相当します。PUT によるアップロードは一時停止され、POST によるアップロードは終了されます。Stopping a debugging session in Microsoft Visual Studio is comparable to closing your app; PUT uploads are paused and POST uploads are terminated. デバッグ時であっても、アプリでは、持続しているアップロードを列挙し、再実行や取り消しを行うことができる必要があります。Even while debugging, your app should enumerate and then restart or cancel any persisted uploads. たとえば、そのデバッグ セッションで以前の操作が重要ではない場合、アプリの起動時に、列挙された持続しているアップロード操作をアプリで取り消すことができます。For example, you can have your app cancel enumerated persisted upload operations at app startup if there is no interest in previous operations for that debug session.

デバッグ セッションでアプリの起動時にダウンロードやアップロードを列挙する際、そのデバッグ セッションで以前の操作が重要ではない場合、列挙された操作をアプリで取り消すことができます。While enumerating downloads/uploads on app startup during a debug session, you can have your app cancel them if there is no interest in previous operations for that debug session. アプリ マニフェストの変更など、Visual Studio プロジェクトの更新があり、アプリがアンインストールされ、もう一度展開された場合、GetCurrentUploadsAsync は、前のアプリの展開を使って作成された操作を列挙できないことに注意してください。Note that if there are Visual Studio project updates, like changes to the app manifest, and the app is uninstalled and re-deployed, GetCurrentUploadsAsync cannot enumerate operations created using the previous app deployment.

開発時にバックグラウンド転送を使うと、完了したアクティブな転送操作の内部キャッシュが同期しなくなる状況が発生する可能性があります。このため、新しい転送操作を開始できない場合や、既存の操作や BackgroundTransferGroup オブジェクトを処理できない場合があります。When using Background Transfer during development, you may get into a situation where the internal caches of active and completed transfer operations can get out of sync. This may result in the inability to start new transfer operations or interact with existing operations and BackgroundTransferGroup objects. 状況によっては、既存の操作を処理しようとすると、クラッシュの原因となる可能性があります。In some cases, attempting to interact with existing operations may trigger a crash. これは、TransferBehavior プロパティが Parallel に設定されている場合に発生する可能性があります。This result can occur if the TransferBehavior property is set to Parallel. この問題は、開発中に特定のシナリオでのみ発生し、アプリのエンド ユーザーには適用されません。This issue occurs only in certain scenarios during development and is not applicable to end users of your app.

Visual Studio を使う 4 つのシナリオで、この問題が発生する可能性があります。Four scenarios using Visual Studio can cause this issue.

  • 既にあるプロジェクトと同じアプリ名を持つ新しいプロジェクトを、別の言語で作成する (C++ から C# など)。You create a new project with the same app name as an existing project, but a different language (from C++ to C#, for example).
  • 既にあるプロジェクトのターゲット アーキテクチャを変更する (x86 から x64 など)。You change the target architecture (from x86 to x64, for example) in an existing project.
  • 既にあるプロジェクトのカルチャを変更する (ニュートラルから en-US など)。You change the culture (from neutral to en-US, for example) in an existing project.
  • 既にあるプロジェクトのパッケージ マニフェストで機能を追加または削除する (エンタープライズ認証を追加するなど)。You add or remove a capability in the package manifest (adding Enterprise Authentication, for example) in an existing project.

機能を追加または削除するマニフェストの更新など、通常のアプリのサービスでは、アプリのエンド ユーザーに対する展開でこの問題は発生しません。Regular app servicing, including manifest updates which add or remove capabilities, do not trigger this issue on end user deployments of your app. この問題を回避するには、アプリのすべてのバージョンを完全にアンインストールし、新しい言語、アーキテクチャ、カルチャ、または機能をもう一度展開します。To work around this issue, completely uninstall all versions of the app and re-deploy with the new language, architecture, culture, or capability. この操作は、スタート画面で行うか、PowerShell と Remove-AppxPackage コマンドレットを使って行うことができます。This can be done via the Start screen or using PowerShell and the Remove-AppxPackage cmdlet.

Windows.Networking.BackgroundTransfer の例外Exceptions in Windows.Networking.BackgroundTransfer

Uniform Resource Identifier (URI) として無効な文字列が、Windows.Foundation.Uri オブジェクトのコンストラクターに渡されると、例外がスローされます。An exception is thrown when an invalid string for a the Uniform Resource Identifier (URI) is passed to the constructor for the Windows.Foundation.Uri object.

.NET: Windows.Foundation.Uri 型は、C# や VB では System.Uri と表示されます。.NET: The Windows.Foundation.Uri type appears as System.Uri in C# and VB.

C# と Visual Basic では、.NET 4.5 の System.Uri クラスと、いずれかの System.Uri.TryCreate メソッドを使って、URI が作成される前にアプリのユーザーから受け取った文字列をテストすることによって、このエラーを回避できます。In C# and Visual Basic, this error can be avoided by using the System.Uri class in the .NET 4.5 and one of the System.Uri.TryCreate methods to test the string received from the app user before the URI is constructed.

C++ では、URI として渡される文字列を試行して解析するメソッドはありません。In C++, there is no method to try and parse a string to a URI. アプリがユーザーから Windows.Foundation.Uri の入力を取得する場合、このコンストラクターを try/catch ブロックに配置する必要があります。If an app gets input from the user for the Windows.Foundation.Uri, the constructor should be in a try/catch block. 例外がスローされた場合、アプリは、ユーザーに通知し、新しいホスト名を要求することができます。If an exception is thrown, the app can notify the user and request a new hostname.

Windows.Networking.backgroundTransfer 名前空間には便利なヘルパー メソッドがあり、Windows.Networking.Sockets 名前空間の列挙値を使ってエラーを処理します。The Windows.Networking.backgroundTransfer namespace has convenient helper methods and uses enumerations in the Windows.Networking.Sockets namespace for handling errors. これは、アプリで特定のネットワーク例外を異なる方法で処理する場合に役立つことがあります。This can be useful for handling specific network exceptions differently in your app.

Windows.Networking.backgroundTransfer 名前空間の非同期メソッドで発生したエラーは、HRESULT 値として返されます。An error encountered on an asynchronous method in the Windows.Networking.backgroundTransfer namespace is returned as an HRESULT value. BackgroundTransferError.GetStatus メソッドは、バックグラウンド転送操作からのネットワーク エラーを WebErrorStatus 列挙値に変換するために使われます。The BackgroundTransferError.GetStatus method is used to convert a network error from a background transfer operation to a WebErrorStatus enumeration value. WebErrorStatus 列挙値のほとんどは、ネイティブ HTTP または FTP クライアント操作から返されるエラーに対応しています。Most of the WebErrorStatus enumeration values correspond to an error returned by the native HTTP or FTP client operation. アプリは特定の WebErrorStatus 列挙値に対するフィルター処理を行い、例外の原因に応じてアプリの動作を変更できます。An app can filter on specific WebErrorStatus enumeration values to modify app behavior depending on the cause of the exception.

パラメーター検証エラーの場合は、例外の HRESULT を使って、その例外の原因となったエラーの詳細情報を確認することもできます。For parameter validation errors, an app can also use the HRESULT from the exception to learn more detailed information on the error that caused the exception. 使うことができる HRESULT 値は、Winerror.h ヘッダー ファイルに記載されています。Possible HRESULT values are listed in the Winerror.h header file. ほとんどのパラメーター検証エラーの場合、返される HRESULTE_INVALIDARG です。For most parameter validation errors, the HRESULT returned is E_INVALIDARG.

重要な APIImportant APIs