Issue with System.Threading.Tasks.Task.Factory.StartNew() in UWP? - c#

I am working on Windows 10 UWP app and my requirement is to upload 5 images on the server with unique value. So, I have used System.Threading.Tasks.Task.Factory.StartNew().Now, when I checked while debugging, I found that randomly sometimes for 2 images, it sends same unique key. Can someone suggest is it better to use System.Threading.Tasks.Task.Factory.StartNew()?
All the images are sent using a web service. My sample code for this is following
WebServiceUtility serviceUtility = new WebServiceUtility();
List<System.Threading.Tasks.Task> tasks = new List<System.Threading.Tasks.Task>();
var cancelSource = new CancellationTokenSource();
cancellationToken = cancelSource.Token;
System.Threading.Tasks.Task currentTask = null;
List<System.Threading.Tasks.Task> uploadTasks = new List<System.Threading.Tasks.Task>();
List<string> uploadedImageIdList = new List<string>();
foreach (var image in _imageCollection)
{
if (!cancellationToken.IsCancellationRequested)
{
currentTask = await System.Threading.Tasks.Task.Factory.StartNew(async () =>
{
string imageName = string.Empty;
string imagePath = string.Empty;
if (image.IsEvidenceImage)
{
imageName = image.EvidencePath.Split('\\')[1];
imagePath = image.EvidencePath;
}
else
{
imageName = image.EvidencePath.Split('#')[1].Split('\\')[1];
imagePath = image.EvidencePath.Split('#')[1];
}
byte[] _imageAsByteArray = await GetEvidenceFromIsoStore(imagePath);
if (null != _imageAsByteArray && _imageAsByteArray.Length > 0)
{
IRestResponse response = await serviceUtility.UploadImage
(_imageAsByteArray, imageName,
new RequestDataGenerator().generateRequestDataForMediaUpload(
(null != _imageItem.I_IS_PRIMARY && "1".Equals(_imageItem.I_IS_PRIMARY) ? "1" : "0"),
evidenceName
));
if (response != null && response.RawBytes.Length > 0)
{
var successMessage = MCSExtensions.CheckWebserviceResponseCode(response.StatusCode);
if (successMessage.Equals(Constants.STATUS_CODE_SUCCESS))
{
byte[] decryptedevidenceresponse = WebserviceED.finaldecryptedresponse(response.RawBytes);
string responseString = Encoding.UTF8.GetString(decryptedevidenceresponse, 0, decryptedevidenceresponse.Length);
JObject reponseObject = JObject.Parse(responseString);
//Debug.WriteLine("Evidence Upload Response : " + Environment.NewLine);
uploadedimageIdList.Add(reponseObject["P_RET_ID"].ToString());
try
{
if (image.IsEvidenceImage)
{
if (await FileExists(image.EvidencePath))
{
StorageFile file = await localFolder.GetFileAsync(image.EvidencePath);
await file.DeleteAsync();
}
}
else
{
string[] evidenceMedia = image.EvidencePath.Split('#');
foreach (string evidenceItem in evidenceMedia)
{
if (await FileExists(evidenceItem))
{
StorageFile file = await localFolder.GetFileAsync(evidenceItem);
await file.DeleteAsync();
}
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
else
{
UserMessageUtil.ShowMessage(successMessage);
}
}
}
}, cancellationToken);
uploadTasks.Add(currentTask);
}
}
await System.Threading.Tasks.Task.WhenAll(uploadTasks.ToArray());

Just make it a separate method:
...
foreach (var image in _imageCollection)
{
if (!cancellationToken.IsCancellationRequested)
{
currentTask = UploadAsync(...);
uploadTasks.Add(currentTask);
}
}
await Task.WhenAll(uploadTasks);
async Task UploadAsync(...)
{
string imageName = string.Empty;
string imagePath = string.Empty;
...
}
Or, a bit more simply at the call site:
...
var uploadTasks = _imageCollection.Select(x => UploadAsync(...));
await Task.WhenAll(uploadTasks);

Related

Return success/error response after making some graph calls

I have the following code to add users to AAD group:
public async Task AddUsersToGroup(IEnumerable<BatchRequestContent> batches)
{
try
{
foreach (var batchRequestContent in batches)
{
var response = await _graphServiceClient
.Batch
.Request()
.WithMaxRetry(10)
.PostAsync(batchRequestContent);
var responses = await response.GetResponsesAsync();
foreach (string key in responses.Keys)
{
var httpResponse = await response.GetResponseByIdAsync(key);
httpResponse.EnsureSuccessStatusCode();
}
}
}
catch (Exception ex)
{
await _log.LogMessageAsync(new LogMessage
{
Message = ex.GetBaseException().ToString(),
RunId = RunId
});
throw;
}
}
I need to update this method to return 'Ok' if all the requests returned a success response, else return 'Error' if any of the requests returned an error response. How would I do that? Please help!
private IEnumerable<BatchRequestContent> GetBatchRequest(IEnumerable<AzureADUser> users, AzureADGroup targetGroup)
{
var batches = new List<BatchRequestContent>();
int maxNoBatchItems = 20;
var batchRequestContent = new BatchRequestContent();
int requestId = 1;
foreach (var user in users)
{
JObject body = new JObject
{
["members#odata.bind"] = $"https://graph.microsoft.com/v1.0/users/{user.ObjectId}"
};
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Patch, $"https://graph.microsoft.com/v1.0/groups/{targetGroup.ObjectId}");
httpRequestMessage.Content = new StringContent(body.ToString(), Encoding.UTF8, "application/json");
batchRequestContent.AddBatchRequestStep(new BatchRequestStep(requestId.ToString(), httpRequestMessage));
if (batchRequestContent.BatchRequestSteps.Count() % maxNoBatchItems == 0)
{
batches.Add(batchRequestContent);
batchRequestContent = new BatchRequestContent();
}
requestId++;
}
if (batchRequestContent.BatchRequestSteps.Count < maxNoBatchItems)
{
batches.Add(batchRequestContent);
}
return batches;
}

i need to create a csv file with UTF-8-BOM encoding, i am using .NET (C#)

public async Task<IActionResult> DownloadCSVResults([FromBody] ProfilesSearchOptions searchOptions)
{
var report = await profileManager.GetRep(searchOptions);
if (report == null)
{
return NotFound();
}
var result = Encoding.UTF8.GetPreamble().Concat(report.Body).ToArray();
return File(result, "text/csv", $"UserProfiles.{DateTime.Now:yyyy.MM.dd.HH.mm.ss}.csv");
}
public async Task<Report> GetRep(ProfilesSearchOptions searchOptions)
{
if (searchOptions == null)
{
return null;
}
var searchResult = await SearchProfiles(tenantDomain, false, searchOptions);
if (searchResult == null)
{
return null;
}
var report = GenerateReportRecord("Trainee");
var fileAsBytes = CsvService.GetCSVAsBytesWithHeaders(searchResult.UsersProfiles.Select(m => new UserProfileViewModel
{
Id = m.Id,
FirstNameAr = m.FirstNameAr,
FatherNameAr = m.FatherNameAr,
FamilyNameAr = m.FamilyNameAr,
FullNameAr = m.FullNameAr,
Email = m.Tenants?.Select(t => t.Email).Aggregate((t1, t2) => t1 + ", " + t2),
Deleted = m.Deleted.HasValue && m.Deleted.Value ? "Yes" : "No",
}));
report.Body = fileAsBytes;
report.Status = ReportStatus.Success;
return report;
}
public static byte[] GetCSVAsBytesWithHeaders<T>(IEnumerable<T> data)
{
using (var memory = new MemoryStream())
using (var writer = new StreamWriter(memory, new UTF8Encoding(true)))
using (var csvWriter = new CsvWriter(writer))
{
csvWriter.Configuration.RegisterClassMap<AutoClassMapWithApplyDisplayNameAttribute<T>>();
csvWriter.WriteRecords<T>(data);
writer.Flush();
var result = memory.ToArray();
return result;
}
}
private Report GenerateReportRecord(string reportTitle, string reportName)
{
return new Report
{
Id = Guid.NewGuid().ToString(),
ReportTitle = $"{reportTitle}.{DateTime.Now:yyyy.MM.dd.HH.mm.ss}",
Status = ReportStatus.InProgress
};
}
these are the three main functions that I am using the CSV file is created but with UTF-8 Encoding but as I mentioned, I needed it to be UTF-8-BOM...any help? and thanks in advance...
the problem is in my csv file some charater are displaying like that => " الاسم الاول "

InvalidOperationException in Memory Streams

I am trying to upload an image to cloudinary cloud. The file converts fine to memory stream but when I try to call upload method of cloudinary to upload the image, I get InvlalidOperationException. What I think is, there is something wrong with converting file to stream.See the image showing error
[HttpPost]
public async Task<IActionResult> AddPhotoForUser(int userId, [FromForm] AddPhotoDto addPhotoDto)
{
try
{
if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
{
return Unauthorized();
}
var userFromRepo = await _datingRepository.GetUser(userId);
var file = addPhotoDto.File;
var uploadResult = new ImageUploadResult();
if (file.Length > 0)
{
using (var stream = file.OpenReadStream())
{
var uploadParams = new ImageUploadParams()
{
File = new FileDescription(file.Name, stream),
Transformation = new Transformation()
.Width(500).Height(500).Crop("fill").Gravity("face")
};
uploadResult = _cloudinary.Upload(uploadParams);
}
}
addPhotoDto.Url = uploadResult.Url.ToString();
addPhotoDto.PublicId = uploadResult.PublicId;
var photo = _mapper.Map<Photo>(addPhotoDto);
if (!userFromRepo.Photos.Any(p => p.IsMain))
{
photo.IsMain = true;
}
userFromRepo.Photos.Add(photo);
if (await _datingRepository.SaveAll())
{
var photoToReturn = _mapper.Map<ReturnPhotoDto>(photo);
return CreatedAtRoute("GetPhoto", new { id = photo.Id }, photoToReturn);
}
return BadRequest("Could not add photo");
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
Can you please share why do you use open stream? You can try:
var imageuploadParams = new ImageUploadParams () {
File = new FileDescription (#"https://res.cloudinary.com/demo/image/upload/v1561532539/sample.jpg"),
PublicId = "myimage",
Transformation = new Transformation().Width(500).Height(500).Crop("fill").Gravity("face")
};
var ImageuploadResult = cloudinary.Upload (imageuploadParams);

How to detect edited or deleted messages on telegram TLSharp

I am trying to detect which message is edited or deleted on a subscribed channel on telegram with TLSharp library in c#.
1- in a while(true) loop I am getting latest updates.
2- when I delete or edit a message for test, I receive TLUpdateChannelTooLong only.
3- then I use client.GetHistoryAsync function to get channel messages, and check their EditDate.
But I don't know how much should I go deep in history and I can not find deleted message with this code easily.
Is there any solution to find deleted/edited messages easy and safe?
Part of my code:
state = await client.SendRequestAsync<TLState>(new TLRequestGetState());
while (true)
{
await Task.Delay(1000);
var req = new TLRequestGetDifference() { Date = state.Date, Pts = state.Pts, Qts = state.Qts };
TLDifference diff = null;
try
{
diff = await client.SendRequestAsync<TLAbsDifference>(req) as TLDifference;
}
catch (Exception ex)
{
HandleThisException(ex);
}
//--
if (diff != null)
{
state = await client.SendRequestAsync<TLState>(new TLRequestGetState());
foreach (var upd in diff.OtherUpdates.OfType<TLUpdateNewChannelMessage>())
{
var tm = (upd.Message as TLMessage);
if (tm == null) { continue; } // ?
var textMessage = tm.Message;
if (tm.Media != null)
{
if (tm.Media.GetType().ToString() == "TeleSharp.TL.TLMessageMediaPhoto")
{
var tLMessageMediaPhoto = (tm.Media as TLMessageMediaPhoto);
textMessage = tLMessageMediaPhoto.Caption;
}
}
try
{
var from = (tm.ToId as TLPeerChannel).ChannelId;
long replyTo = tm.ReplyToMsgId == null ? 0 : (long)tm.ReplyToMsgId;
await AnalyzeNewMessage( ... );
}
catch (Exception exParsing)
{
HandleThisException(exParsing);
}
}
// Checking Edited/Deleted Messages
foreach(var upLong in diff.OtherUpdates.OfType<TLUpdateChannelTooLong>())
{
TLChannel theChat = null;
foreach(var chat in diff.Chats.OfType<TLChannel>())
{
if(chat.Id == upLong.ChannelId) { theChat = chat; break; }
}
if (theChat != null)
{
var x = await client.GetHistoryAsync(
new TLInputPeerChannel { ChannelId = theChat.Id, AccessHash = (long)theChat.AccessHash },
0,-1,2
); // checking only 2 last messages!
var ChMsgs = x as TLChannelMessages;
foreach (var msg in ChMsgs.Messages.OfType<TLMessage>())
{
if(msg.EditDate != null)
{
var txt = msg.Message;
if (msg.Media != null)
{
if (msg.Media.GetType().ToString() == "TeleSharp.TL.TLMessageMediaPhoto")
{
txt = (msg.Media as TLMessageMediaPhoto).Caption;
}
}
await AnalyzeEditedMessage( ... );
}
}
}
}
}
}

How do I detect canceled asynchronous post

I use the following code to upload a file and form data asynchronous. What do I need to change in order to detect if the transfer has been cancelled or interrupted and then take proper action?
[HttpPost]
public async Task<object> UploadFile()
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType));
}
var streamProvider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/App_Data/Temp/"));
try
{
var filesReadToProvider = await Request.Content.ReadAsMultipartAsync(streamProvider);
var paramName = "formInput";
var formStreamToRead = filesReadToProvider.Contents.First(x => x.Headers.ContentDisposition.Name == $"\"{formInput}\"");
var formInput = await formStreamToRead.ReadAsStringAsync();
foreach (var fileData in streamProvider.FileData)
{
var fileName = "";
if (string.IsNullOrEmpty(fileData.Headers.ContentDisposition.FileName))
{
fileName = Guid.NewGuid().ToString();
}
fileName = fileData.Headers.ContentDisposition.FileName;
if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
{
fileName = fileName.Trim('"');
}
if (fileName.Contains(#"/") || fileName.Contains(#"\"))
{
fileName = Path.GetFileName(fileName);
}
File.Move(fileData.LocalFileName, Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/"), Path.GetDirectoryName(fileName) + Guid.NewGuid() + Path.GetExtension(fileName)));
}
return Request.CreateResponse(HttpStatusCode.OK);
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
}
}

Categories