/// <summary> /// Initializes a new instance of the <see cref="SensusUI.ShareLocalDataStorePage"/> class. /// </summary> /// <param name="localDataStore">Local data store to display.</param> public ShareLocalDataStorePage(LocalDataStore localDataStore) { _cancellationTokenSource = new CancellationTokenSource(); Title = "Sharing Local Data Store"; StackLayout contentLayout = new StackLayout { Orientation = StackOrientation.Vertical, VerticalOptions = LayoutOptions.FillAndExpand }; Label statusLabel = new Label { FontSize = 20, HorizontalOptions = LayoutOptions.FillAndExpand }; contentLayout.Children.Add(statusLabel); ProgressBar progressBar = new ProgressBar { Progress = 0, HorizontalOptions = LayoutOptions.FillAndExpand }; contentLayout.Children.Add(progressBar); Button cancelButton = new Button { Text = "Cancel", FontSize = 20, HorizontalOptions = LayoutOptions.FillAndExpand }; cancelButton.Clicked += async(o, e) => { await Navigation.PopAsync(); }; contentLayout.Children.Add(cancelButton); new Thread(() => { string sharePath = UiBoundSensusServiceHelper.Get(true).GetSharePath(".json"); bool errorWritingShareFile = false; try { // step 1: gather data. Device.BeginInvokeOnMainThread(() => statusLabel.Text = "Gathering data..."); List <Datum> localData = localDataStore.GetDataForRemoteDataStore(_cancellationTokenSource.Token, progress => { Device.BeginInvokeOnMainThread(() => { progressBar.ProgressTo(progress, 250, Easing.Linear); }); }); // step 2: write gathered data to file. if (!_cancellationTokenSource.IsCancellationRequested) { Device.BeginInvokeOnMainThread(() => { progressBar.ProgressTo(0, 0, Easing.Linear); statusLabel.Text = "Writing data to file..."; }); using (StreamWriter shareFile = new StreamWriter(sharePath)) { shareFile.WriteLine("["); int dataWritten = 0; foreach (Datum localDatum in localData) { if (_cancellationTokenSource.IsCancellationRequested) { break; } shareFile.Write((dataWritten++ == 0 ? "" : "," + Environment.NewLine) + localDatum.GetJSON(localDataStore.Protocol.JsonAnonymizer)); if (localData.Count >= 10 && (dataWritten % (localData.Count / 10)) == 0) { Device.BeginInvokeOnMainThread(() => progressBar.ProgressTo(dataWritten / (double)localData.Count, 250, Easing.Linear)); } } shareFile.WriteLine(Environment.NewLine + "]"); shareFile.Close(); } } } catch (Exception ex) { errorWritingShareFile = true; string message = "Error writing share file: " + ex.Message; UiBoundSensusServiceHelper.Get(true).FlashNotificationAsync(message); UiBoundSensusServiceHelper.Get(true).Logger.Log(message, LoggingLevel.Normal, GetType()); } if (_cancellationTokenSource.IsCancellationRequested || errorWritingShareFile) { // always delete the file on cancel / error try { File.Delete(sharePath); } catch (Exception) { } // the only way to get a cancellation event is to back out of the window, so only pop if there was an error if (errorWritingShareFile) { Device.BeginInvokeOnMainThread(async() => await Navigation.PopAsync()); } } else { Device.BeginInvokeOnMainThread(async() => { await Navigation.PopAsync(); UiBoundSensusServiceHelper.Get(true).ShareFileAsync(sharePath, "Sensus Data"); }); } }).Start(); Content = new ScrollView { Content = contentLayout }; }
public ShareLocalDataStorePage(LocalDataStore localDataStore) { _cancel = false; Title = "Sharing Local Data Store"; StackLayout contentLayout = new StackLayout { Orientation = StackOrientation.Vertical, VerticalOptions = LayoutOptions.FillAndExpand }; Label statusLabel = new Label { FontSize = 20, HorizontalOptions = LayoutOptions.FillAndExpand }; contentLayout.Children.Add(statusLabel); ProgressBar progressBar = new ProgressBar { Progress = 0, HorizontalOptions = LayoutOptions.FillAndExpand }; contentLayout.Children.Add(progressBar); Button cancelButton = new Button { Text = "Cancel", FontSize = 20, HorizontalOptions = LayoutOptions.FillAndExpand }; cancelButton.Clicked += async(o, e) => { await Navigation.PopAsync(); }; contentLayout.Children.Add(cancelButton); new Thread(async() => { string sharePath = UiBoundSensusServiceHelper.Get(true).GetSharePath(".json"); bool errorWritingShareFile = false; try { Device.BeginInvokeOnMainThread(() => statusLabel.Text = "Gathering data..."); List <Datum> localData = localDataStore.GetDataForRemoteDataStore(progress => { Device.BeginInvokeOnMainThread(() => { progressBar.ProgressTo(progress, 250, Easing.Linear); }); }, () => { return(_cancel); }); Device.BeginInvokeOnMainThread(() => { progressBar.ProgressTo(0, 0, Easing.Linear); statusLabel.Text = "Writing data to file..."; }); using (StreamWriter shareFile = new StreamWriter(sharePath)) { int dataWritten = 0; foreach (Datum datum in localData) { shareFile.WriteLine(datum.GetJSON(localDataStore.Protocol.JsonAnonymizer)); if ((++dataWritten % (localData.Count / 10)) == 0) { Device.BeginInvokeOnMainThread(() => progressBar.ProgressTo(dataWritten / (double)localData.Count, 250, Easing.Linear)); } } shareFile.Close(); } } catch (Exception ex) { errorWritingShareFile = true; string message = "Error writing share file: " + ex.Message; SensusServiceHelper.Get().FlashNotificationAsync(message); SensusServiceHelper.Get().Logger.Log(message, LoggingLevel.Normal, GetType()); await Navigation.PopAsync(); } if (!_cancel && !errorWritingShareFile) { Device.BeginInvokeOnMainThread(async() => await Navigation.PopAsync()); SensusServiceHelper.Get().ShareFileAsync(sharePath, "Sensus Data"); } }).Start(); Content = new ScrollView { Content = contentLayout }; }