Reputation: 174
In my code, the progress bar freezes when it reaches the "Updating portal files record..." status message. However, the subsequent task, UpdatePortalFileApprovalAsync, does actually complete successfully—I can confirm that the record updates as expected.
Oddly, everything works perfectly on our server, both in Visual Studio (debug and release modes). But when deployed to my client’s server, the task completes, yet the progress bar stops updating and appears frozen.
I'm looking for insight into why this might be happening specifically on the client’s server and how to ensure the progress bar reflects the task completion accurately.
Here's my code:
private void dateEdit_ArrivalDate_EditValueChanged(object sender, EventArgs e)
{
if (dateEdit_ArrivalDate.EditValue != null)
dateTimePicker_ContinuousServiceDate.Value = (DateTime)dateEdit_ArrivalDate.EditValue;
}
#region Passport
private async void button_ApprovePassport_Click(object sender, EventArgs e)
{
await ProcessPassportPdfAsync();
}
private async Task ProcessPassportPdfAsync()
{
LoadingForm loadingForm = new LoadingForm();
try
{
// Show loading form in a non-blocking way
loadingForm.Show(this);
// Start progress at 0%
loadingForm.UpdateProgress(0);
loadingForm.UpdateStatus("Initializing...");
// Check if a document is selected
if (gridView_PortalDocs.IsSelected())
{
var PortalDoc = gridView_PortalDocs.GetSelectedDataRow<PortalDocumentInfoModel>();
if (PortalDoc != null)
{
// Validate the document before proceeding
if (!ValidateDocumentApproval(PortalDoc))
{
return; // Exit if validation fails
}
// Update progress to 10%
loadingForm.UpdateProgress(10);
loadingForm.UpdateStatus("Retrieving user signature...");
// Get the system user info
var systemUserID = 345; // Replace 345 (Stefi's ID) with cGlobal.SystemUserID
var SystemUserSignature = Controller.GetSystemUserSignature(systemUserID);
// Check if the signature was retrieved successfully
if (SystemUserSignature == null || SystemUserSignature.Count == 0)
{
cGlobal.ShowErrorMessage("User signature not found. Please add one in Access Control.");
return;
}
// Store the user info for both stamping and approval
var user = SystemUserSignature[0];
// Update progress to 30%
loadingForm.UpdateProgress(30);
loadingForm.UpdateStatus("Fetching document...");
EmployeePortalService EPS = new EmployeePortalService();
var Data = await EPS.GetDocument(PortalDoc.PortalFileID);
if (Data != null && !string.IsNullOrEmpty(Data.FileData))
{
// Convert base64 string to byte array
byte[] fileBytes = Convert.FromBase64String(Data.FileData);
// Update progress to 50%
loadingForm.UpdateProgress(50);
loadingForm.UpdateStatus("Stamping PDF...");
// Create a memory stream from the byte array
using (MemoryStream inputStream = new MemoryStream(fileBytes))
{
// Process the PDF (stamp it)
using (MemoryStream processedStream = StampPdf(inputStream, user))
{
// This is just to check the stamp is working and to make alterations.
// Save the processed PDF to a temporary file
//string tempFilePath = Path.Combine(Path.GetTempPath(), $"StampedPassport_{Guid.NewGuid()}.pdf");
//File.WriteAllBytes(tempFilePath, processedStream.ToArray());
//// Open the PDF with the default viewer
//System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo(tempFilePath) { UseShellExecute = true });
// Convert the processed stream back to a base64 string
string processedBase64 = Convert.ToBase64String(processedStream.ToArray());
// Update progress to 70%
loadingForm.UpdateProgress(70);
loadingForm.UpdateStatus("Preparing stamped document...");
// Call the API to reupload the file with workerRefID and documentType
string UploadResult = await UploadStampedPdfAsync(PortalDoc, processedBase64, user.Forename, loadingForm);
if (UploadResult == "Success")
{
// Update progress to 100%
loadingForm.UpdateProgress(100);
loadingForm.Close();
loadingForm.Dispose();
cGlobal.ShowInfoMessage("Passport PDF processed and approved successfully.", "Success");
}
else
{
loadingForm.Close();
loadingForm.Dispose();
cGlobal.ShowErrorMessage($"Error during upload: {UploadResult}", "Upload Error");
}
}
}
}
else
{
cGlobal.ShowErrorMessage("The document data could not be retrieved from the server or is empty.");
}
RefreshPortalDocuments();
}
else
{
cGlobal.ShowErrorMessage("The selected document information is invalid.");
}
}
else
{
cGlobal.ShowInfoMessage("Please select a document to process.");
}
}
catch (Exception ex)
{
cGlobal.ShowErrorMessage($"An error occurred while processing the passport PDF: {ex.Message}");
}
finally
{
loadingForm.Close();
loadingForm.Dispose();
}
}
private async Task<string> UploadStampedPdfAsync(PortalDocumentInfoModel portalDoc, string base64FileContent, string approvedBy, LoadingForm loadingForm)
{
try
{
using (HttpClient client = new HttpClient())
{
// Prepare the request URL and parameters
string apiUrl = "Upload file api endpoitn";
// DefaultAPIKey and JGWAPIKey in the config as well. Not sure why they gave me two keys
string apiKey = HMEmployees.Properties.Settings.Default.DefaultAPIKey;
string uploadUrl = $"{apiUrl}{apiKey}";
// Create the payload
var uploadPayload = new
{
workerRefID = portalDoc.WorkerReferenceID ?? 0, // Ensure it's not null
fileContent = base64FileContent, // Base64 encoded file content
documentType = portalDoc.Type // Document type (e.g., "Hygiene")
};
// Serialize the payload to JSON
string jsonPayload = JsonConvert.SerializeObject(uploadPayload);
var content = new StringContent(jsonPayload, Encoding.UTF8, "application/json");
loadingForm.UpdateProgress(80);
loadingForm.UpdateStatus("Uploading stamped document...");
// Send the POST request
HttpResponseMessage response = await client.PostAsync(uploadUrl, content);
if (response.IsSuccessStatusCode)
{
JGWService JGW = new JGWService();
loadingForm.UpdateProgress(90);
loadingForm.UpdateStatus("Updating portal files record...");
// Call UpdatePortalFileApprovalAsync and check the result
var updateResult = await JGW.UpdatePortalFileApprovalAsync(portalDoc.WorkerReferenceID ?? 0, portalDoc.Type, approvedBy);
if (updateResult.IsSuccess)
{
// Delete the original unstamped portal file. This needs to be commented in when going live.
//loadingForm.UpdateProgress(95);
//loadingForm.UpdateStatus("Deleting original unstamped file...");
// await DeletePortalDocumentAsync(portalDoc);
return "Success"; // The upload and update were both successful
}
else
{
string errorMessage = $"Update Failed: {updateResult.DetailedError ?? "No detailed error"}, {updateResult.Message ?? "No message available"}";
return errorMessage;
}
}
else
{
string errorResponse = await response.Content.ReadAsStringAsync();
string errorMessage = $"Failed: {response.StatusCode}, {errorResponse}";
return errorMessage;
}
}
}
catch (Exception ex)
{
return $"Exception: {ex.Message}";
}
}
The loading form in case that's the issue:
public partial class LoadingForm : Form
{
private Label LabelStatus;
private ProgressBar ProgressBar;
public LoadingForm()
{
InitializeComponent();
}
public void UpdateStatus(string status)
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() => UpdateStatus(status)));
return;
}
label_Status.Text = status;
}
// New method to update the progress bar value
public async void UpdateProgress(int targetValue)
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() => UpdateProgress(targetValue)));
return;
}
// Start from the current progress bar value
int currentValue = progressBar_ProgressBar.Value;
// Increment up to the target value in small steps
int incrementStep = 1; // Size of each step
int delay = 20; // Delay in milliseconds between steps
while (currentValue < targetValue)
{
currentValue += incrementStep;
if (currentValue > targetValue)
{
currentValue = targetValue; // Ensure we don't go past the target
}
progressBar_ProgressBar.Value = currentValue;
await Task.Delay(delay); // Small delay to make the increment visible
}
}
}
I've tried to do this:
var updateResult = await Task.Run(() => JGW.UpdatePortalFileApprovalAsync(portalDoc.WorkerReferenceID ?? 0, portalDoc.Type, approvedBy));
in case it was some kind of blocking problem but I had the same result.
Any suggestions would be appreciated.
edit: Removed actual API endpoint lol
Upvotes: 0
Views: 70