-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Added background download creation. #890
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@Romasz What I understand, $skip query parameter is not supported (yet) as a valid parameter according to the documentation btw don't hesitate to vote here https://onedrive.uservoice.com/forums/262982-onedrive/suggestions/11357844-please-add-the-odata-skip-query-option-to-a |
|
@EricVernie You are probably right. Then maybe GetItems(..) methods should have some more description and checkout for 1000? You also have my votes. |
| { | ||
| downloader.SetRequestHeader(item.Key, item.Value.First()); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason this is in a Task.Run()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ScottIsAFool The MSDN says that if you create large number of requests then performance of UI can get degraded and we don't know if users won't use this method in a loop.
Creating a large number of transfers on the main UI thread with CreateDownload can result in degraded performance of your app's UI. If you are queuing up a large number of transfers, it is recommended that you call CreateDownload on a background worker thread as in the following example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Romasz please set ConfigureAwait for each task to false unless contest needs to be maintained like with BitmapImage.
Check other services / CacheBase
You shouldn't need to worry about how and on what thread lib code usually works
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hermitdave I concur, will correct that later once I get back to project. BTW - as I understand, in this particular case where Task.Run is the last method without code to follow, putting ConfigureAwait won't change anything - am I right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Romasz consider using
CreateDownloadAsync instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hermitdave CreateDownlaodAsync needs requestBodyStream which cannot be null, therefore I'm using non-async version. I will put ConfigureAwait(false) in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No its okay. I don't think Task.Run will help there. We can look at it if there is a perf issue.
ConfigureAwait might help here
var requestMessage = Provider.Drive.Items[oneDriveId].Content.Request().GetHttpRequestMessage();
await Provider.AuthenticationProvider.AuthenticateRequestAsync(requestMessage).AsAsyncAction().AsTask(cancellationToken);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hermitdave That ones - yeah. I'm just thinking now if not to put almost whole method, starting from requestMessage under Task.Run - then there also won't be need for configuring await - what do you think about this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly.. Let me review the code later
| } | ||
|
|
||
| return await Task.Run(() => downloader.CreateDownload(requestMessage.RequestUri, destinationFile), cancellationToken); | ||
| return await Task.Run( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hermitdave I've moved the wohole code to Task.Run - what do you think about it? Do we need also configuring await here?
|
btw no background dl for storage folder @Romasz ? |
|
@hermitdave This is harder to handle as there are many cases to be considered. Do you know if there is a method calling OneDrive to download folder as a compressed zip file? In very simple version the method can just list every file in every subfolder and create a separate background download, but I'm not sure if it's a good idea, as there is probably a limit of background downloads being run. What do you think? |
|
@Romasz we can provide user specified parallel downloads. The background downloader has a property. @EricVernie and @deltakosh any thoughts? |
|
@hermitdave You mean the TransferGroup property? I will need to give this couple of tries in upcoming days. |
|
@hermitdave I will see what I can do, though need some time for this (quite lot of work around). |
|
@Romasz true that can be added later |
| async () => | ||
| { | ||
| var requestMessage = Provider.Drive.Items[oneDriveId].Content.Request().GetHttpRequestMessage(); | ||
| await Provider.AuthenticationProvider.AuthenticateRequestAsync(requestMessage).AsAsyncAction().AsTask(cancellationToken); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using .AsAsyncAction().AsTask() just to pass a CancellationToken will probably do nothing for this method.
it's the AuthenticateRequestAsync that should have CancellationToken support!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pedrolamas I wonder if we need those cancellation tokens there, as this part of code runs on separate thread which has it's own cancellation token Task.Run(Action, cancellationToken).
I would like to know how this behaves in case od cancel signal, the thread is ended instantly/methods interrupted? Though I don't know where I can find such information and don't have much time now to go across reference source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be fair, I'm not quite fond with using Task.Run there, but I can understand your reasoning!
Libraries should not lie about async work, and there is a "rule" about not using Task.Run() inside of them and just let the developers do that from the UI!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the problem is that in this instance the docs are clear that executing this from UI thread will result in perf issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pedrolamas I think we have two choices - leave as it is now, even against etiquette or provide a description in method like 'Consider running this method on separate thread while creating large number of download operations'.
Personally I like the first solution, but I've nothing against the second and I completely understand your reasons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Etiquette is great but we must be pragmatic. We have to do everything that we can to simplify usages of the API. If we know that this method has to run on a thread, then run it on a thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough, in that case I think this is ready to merge!
#883 - I've added two methods creating background download - one in OneDriveStorageFile and one in OneDriveService. I've also added cancellation in method responsible for getting items.
@EricVernie The GetItemsAsync(...) method of OneDriveStorageFolder allows to download up to 1000 items, due to SDK limit, otherwise it will throw exception. Another problem is that the request doesn't accept Skip(). In that case if you start with index 2 and want to download 1000 items - it will also throw exception. Do you have any ideas for that?