Hello i have a next code:
When thumbnail is tapped i have to download file if it doesn't exist localy, or open if exists.
The problem is that if i make very quick two taps - it downloads same file two times - how to prevent this?
As you can see i tried using bool - didn't help.
Tried also using private static SemaphoreSlim TapSemaphore = new SemaphoreSlim(1, 1); - didn't help
public bool IsCurrentlyDownloading = false;
private async void assetThumbnail_Tapped(object sender, TappedRoutedEventArgs e)
{
await OpenOrDownload();
}
private async Task OpenOrDownload()
{
if (FileIsDownloaded == true)
{
string filename = Util.GetLocalFileName(CustomerAsset.file.id, "CustomerAssetFile");
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = false;
var sampleFile = await ApplicationData.Current.LocalFolder.GetFileAsync(filename);
await Windows.System.Launcher.LaunchFileAsync(sampleFile, options);
}
else
{
if (!IsCurrentlyDownloading)
{
IsCurrentlyDownloading = true;
DownloadFiles();
}
}
}
Why don't you use a flag (bool, sync object, something) to mark that the downloading or displaying operation is in progress and in this case do not show it.
Rather conceptually, something like this:
public bool IsCurrentlyDownloading = false;
bool isWorking = false;
private async void assetThumbnail_Tapped(object sender, TappedRoutedEventArgs e)
{
if(!isWorking)
await OpenOrDownload();
}
private async Task OpenOrDownload()
{
isWorking = true;
if (FileIsDownloaded == true)
{
string filename = Util.GetLocalFileName(CustomerAsset.file.id, "CustomerAssetFile");
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = false;
var sampleFile = await ApplicationData.Current.LocalFolder.GetFileAsync(filename);
await Windows.System.Launcher.LaunchFileAsync(sampleFile, options);
}
else
{
if (!IsCurrentlyDownloading)
{
IsCurrentlyDownloading = true;
DownloadFiles();
}
}
isWorking = false;
}
Related
I'm using the ZXing plugin to scan bar codes and I'm using a custom overlay to display information and make a button visible/invisible when I need to perform an action, which in this case is to set a flag and make the button invisible again.
In this code I set up the scanning plugin:
MyButton_Scan.Click += async (sender, e) =>
{
var selectedEvent = string.Format("{0}", MyEventsSpinner.GetItemAtPosition(MyEventsSpinner.SelectedItemPosition));
if (selectedEvent.ToUpper() != "SELECT EVENT")
{
MobileBarcodeScanner.Initialize(Application);
scanner = new MobileBarcodeScanner();
scanner.UseCustomOverlay = true;
zxingOverlay = LayoutInflater.FromContext(this).Inflate(Resource.Layout.scanner, null);
MyScanScreenButton = zxingOverlay.FindViewById<Android.Widget.Button>(Resource.Id.okButton);
MyScanScreenButton.Click += btnOk_Click;
MyScanScreenButton.Visibility = Android.Views.ViewStates.Invisible;
scanner.CustomOverlay = zxingOverlay;
var opt = new MobileBarcodeScanningOptions();
opt.DelayBetweenContinuousScans = 5000;
//Start scanning
scanner.ScanContinuously(this, opt, HandleScanResult);
} else
{
Utils.showMessage("Please select an event from the drop down list");
}
};
The code that handles the scan result and button click:
void btnOk_Click(object sender, System.EventArgs e)
{
popUpOpen = false;
MyScanScreenButton.Visibility = Android.Views.ViewStates.Invisible;
}
void HandleScanResult(ZXing.Result result)
{
if (!popUpOpen)
{
Boolean ConversionGood = true;
TextView MyTextView = zxingOverlay.FindViewById<TextView>(Resource.Id.ticketInfo);
Int32 convertedResult = 0;
Stream successbeepStream = GetType().Assembly.GetManifestResourceStream("eTicket_Scanner.beep.wav");
Stream failbeepStream = GetType().Assembly.GetManifestResourceStream("eTicket_Scanner.buzzer.wav");
MyTextView.SetBackgroundColor(Color.White);
try
{
convertedResult = Convert.ToInt32(result.Text);
}
catch (Exception ex)
{
ConversionGood = false;
bool isSuccess = _simpleAudioPlayer.Load(failbeepStream);
_simpleAudioPlayer.Play();
popUpOpen = true;
MyScanScreenButton.Visibility = Android.Views.ViewStates.Visible;
MyTextView.SetBackgroundColor(Color.Red );
MyTextView.Text = "Not a valid ticket for this event.\nErrorif applicable): " + ex.Message;
}
string scanResult = "";
if (ConversionGood)
{
scanResult = MyEventsService.VerifyScannedCode(MyUser.Username, MyUser.Password, currentEventID, convertedResult);
if (scanResult == "Y")
{
MyTextView.SetBackgroundColor(Color.Green);
bool isSuccess = _simpleAudioPlayer.Load(successbeepStream);
popUpOpen = true;
MyTextView.SetBackgroundColor(Color.Green);
MyTextView.Text = MyEventsService.GetTicketInfo(MyUser.Username, MyUser.Password, currentEventID, convertedResult);
_simpleAudioPlayer.Play();
MyScanScreenButton.Visibility = Android.Views.ViewStates.Visible;
}
else
{
bool isSuccess = _simpleAudioPlayer.Load(failbeepStream);
popUpOpen = true;
MyTextView.SetBackgroundColor(Color.Red);
MyTextView.Text = MyEventsService.GetFailedScanTicketInfo(MyUser.Username, MyUser.Password, currentEventID, convertedResult);
_simpleAudioPlayer.Play();
MyScanScreenButton.Visibility = Android.Views.ViewStates.Visible;
}
}
}
}
Its not a very complicated app, scan barcodes and verify the code, set the color of the textview background and display the info. The "Ok" button is never visible, but if I click in the space where the button should appear, it executes the button click code. I'm assuming that there is some sort of thread issue here with the interface, but anything I've tried with the thread hasn't worked. Anyone have any ideas?
In my event load of my form , I call a method loadDg:
private void form_Load(object sender, EventArgs e)
{
loadDg();
}
and
private async Task loadDg()
{
pictureLoading.Visible = true;
await Task.Run(() => { string[] datas = db.row("select * from products");
string[] datas2 = db.row("select * from users");
double one = Convert.ToInt32(datas[0]);
label1.Text = one.toString();
//....
});
pictureLoading.Visible = false; //hide gif animation
}
in my code , db.row This method always returns only 1 row ( string array) , but my ui freezes still , i try update UI continuously with async without freeze at startup
There is nothing to prevent your code run asynchronously. pictureLoading will be invisible even before task is completed. You should fix cross-thread problem and logic of the UI as this:
private void form_Load(object sender, EventArgs e)
{
pictureLoading.Visible = true;
loadDg();
}
private async Task loadDg()
{
await Task.Run(() =>
{
string[] datas = db.row("select * from products");
string[] datas2 = db.row("select * from users");
double one = Convert.ToInt32(datas[0]);
label1.BeginInvoke((Action)delegate ()
{
label1.Text = one.toString();
//hide gif animation
pictureLoading.Visible = false;
});
//....
});
}
Unnecessarily jumping between threads/context should be avoided.
This is an with better resource usage:
private async void form_Load(object sender, EventArgs e)
{
pictureLoading.Visible = true;
try
{
label1.Text = await LoadDgAsync();
}
catch
{
// error handling
}
finally
{
pictureLoading.Visible = false;
}
}
private Task<string> LoadDgAsync()
{
return Task.Run(() =>
{
string[] datas = db.row("select * from products");
string[] datas2 = db.row("select * from users");
double one = Convert.ToInt32(datas[0]);
//....
return one.toString();
});
}
You are calling the loadDg() function synchronously.
Unless you await the loadDg() function call (since its return type is Task) and make the form_Load function asynchronous the function call will be synchronous.
The correct way to fix it is...
private async void form_Load(object sender, EventArgs e)
{
await loadDg();
}
I've got a problem with TLSharp method IsPhoneRegisteredAsync(...).
It always returns true, no matter the number I'm trying to check. Even for an input like "asdhbqaihbqwieuashdq23934327940scj0" it returns true.
Thanks for your help.
My code:
private void button1_Click(object sender, EventArgs e)
{
connectClient(SETS.API_ID, SETS.API_HASH);
}
private async void connectClient(int api_id, string api_hash)
{
client = new TelegramClient(api_id, api_hash);
api_ID_tb.Text = api_id.ToString();
api_hash_tb.Text = api_hash;
await client.ConnectAsync();
if (client.IsConnected)
{
MessageBox.Show("Connect Succefull");
}
}
async void CheckNumber(string number)
{
bool q = await client.IsPhoneRegisteredAsync(number);
MessageBox.Show(q.ToString());
}
private void numberCheckBtn_Click(object sender, EventArgs e)
{
CheckNumber(number_tb.Text);
}
Got same problem.
That`s how i solved it:
var req = new Auth.TLRequestSendCode
{
PhoneNumber = myPhone,
ApiId = ApiID,
ApiHash = ApiHash
};
var resp = await client.SendRequestAsync<Auth.TLSentCode>(req);
var phoneCodeHash = resp.PhoneCodeHash;
var isRegistered = resp.PhoneRegistered;
This is the same code as SendCodeRequestAsync (witch return only hash) but now we have access to Auth.TLSentCode.PhoneRegistered
I have problem with getting of FolderBrowserDialog in white. I think that it should be assigned as a modal window but it isn't.
FolderBrowserDialog in DialogService.cs:
public FolderBrowserResult ShowFolderbrowserDialog(string storageFolder)
{
var dialog = new FolderBrowserDialog
{
Description = storageFolder
};
var result = new FolderBrowserResult
{
Result = dialog.ShowDialog() != DialogResult.OK,
Path = dialog.SelectedPath
};
return result;
}
Method called after click on browse button:
private void OnBrowseForTargetFolder(object sender, RoutedEventArgs e)
{
var result = dialogService.ShowFolderbrowserDialog(Properties.Resources.StorageFolder);
if (result.Result) return;
Project.PathToStorage = result.Path;
completePath = string.Format("{0}\\{1}", result.Path, Guid.NewGuid());
Directory.CreateDirectory(completePath);
}
Test:
public class LoggerTests
{
private Application application;
private MainWindowPage mainWindowPage;
[TestInitialize]
public void TestInitialize()
{
application = Application.Launch(#"PML.exe");
StartBlankApplication();
}
[TestMethod]
public void StartExistingProject()
{
mainWindowPage.StartExistingProjectButton.Click();
var modalWindows = new List<Window>();
Retry.For(() =>
{
modalWindows = mainWindowPage.applicationWindow.ModalWindows();
}, TimeSpan.FromSeconds(5));
var mod = modalWindows;
}
private MainWindowPage StartBlankApplication()
{
var appWindow = application.GetWindow("PML");
mainWindowPage = new MainWindowPage(appWindow);
return mainWindowPage;
}
private NewProjectConfigurationPage ConfigureBlankProject()
{
Window secondAppWindow = null;
Retry.For(() =>
{
secondAppWindow = application.GetWindow("PML");
}, TimeSpan.FromSeconds(5));
var newProjectConfiguration = new NewProjectConfigurationPage(secondAppWindow);
newProjectConfiguration.VesselName.Text = "Test";
newProjectConfiguration.BrowseButton.Click();
return newProjectConfiguration;
}
}
In StartExistingProject method is problem that variable mod is empty. And no FolderBrowserDialog is opened. But when I run app normally everything runs OK.
Solved - There must be setted owner to modal dialog. So
var wrapper = new WindowWrapper(this);
dialog.ShowDialog(wrapper)
solved my problem.
I am creating a Windows Phone 8.1 Universal App. There are some screens on my app. On the first screen, i am navigate my screen to second screen. When i press hardware back button on second screen. My previous page state lost.
I am unable to rectify where was the problem. Here is the code below:
Screen 1 Code
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
this.NavigationCacheMode = NavigationCacheMode.Enabled;
if (e.NavigationMode == NavigationMode.New)
{
BindQuickDateComboBox();
if (Frame.BackStack.Count > 0)
{
var lastPage = Frame.BackStack.Last().SourcePageType;
if (lastPage != null && lastPage.FullName == "Cryoserver.AppLogin")
{
Frame.BackStack.Clear();
}
}
}
}
async private void appBarSearch_Click(object sender, RoutedEventArgs e)
{
try
{
if (IsValidateForm())
{
ProgressBar.IsVisible = true;
cmdBarSearch.IsEnabled = false;
if (await conn.Table<SearchQuery>().CountAsync() > 0)
{
await conn.DropTableAsync<SearchQuery>();
await conn.CreateTableAsync<SearchQuery>();
}
var searchTerms = new SearchQuery();
if (Convert.ToString(cmbQuickDate.SelectedItem) != "Any Date")
{
searchTerms.FromDate = pickerFromDate.Date.ToString("d MMM yyyy");
searchTerms.FromTime = pickerFromTime.Time.ToString();
searchTerms.ToDate = pickerToDate.Date.ToString("d MMM yyyy");
searchTerms.ToTime = pickerToTime.Time.ToString();
}
searchTerms.SearchKeywords = txtKeywords.Text;
searchTerms.Parties = txtParties.Text;
searchTerms.Contributer = txtFrom.Text;
searchTerms.Viewer = txtTo.Text;
searchTerms.AttachmentName = txtAttName.Text;
searchTerms.AttachmentKeywords = txtAttKeywords.Text;
searchTerms.SearchReason = txtSearchReason.Text;
searchTerms.IsHighLight = "false";
await conn.InsertAsync(searchTerms);
object resultMails = await SearchEmailArchive();
if (!String.IsNullOrEmpty(Convert.ToString(resultMails)))
{
GlobalInfo.SelectedRow = -1;
GlobalInfo.SearchPageIndex = -1;
GlobalInfo.IsFindKeyword = false;
var archiveMails = JsonConvert.DeserializeObject<SearchResult>(resultMails.ToString());
Frame.Navigate(typeof(MailList), archiveMails);
}
ProgressBar.IsVisible = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
ProgressBar.IsVisible = false;
}
cmdBarSearch.IsEnabled = true;
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
}
Screen 2
I too used this code in second screen and also after removing this code. But it didn't work for me. Still the same problem.
void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
if (Frame.CanGoBack)
{
e.Handled = true;
Frame.GoBack();
}
}
Screen 1 state is Blank and behaves as a freshly loaded screen. Why?
Any help would be much appreciated.
I would try setting NavigationCacheMode="Required" in the constructor/XAML instead.