TPL Dataflow , finish a Block , re-create a BLock - task-parallel-library

I am using TPL Dataflow to display a video while first passing the data via TCP to a board. I am using CancellationTokenSource to cancel the Block activities. But the problem is, when I am re-running the "CreateVideoProcessingNetwork" function I have no response. The .Post() command returns false. How should I re-create or "rerun" a TPL Dataflow? here is the code :
private void TPL_Click(object sender, EventArgs e)
{
CreateVideoProcessingNetwork();
}
public async void CreateVideoProcessingNetwork()
{
string video_path = #"C:\.....\video_640x360_360p.mp4";
_canceller = new CancellationTokenSource();
/****************** METHOD 1 - with yield *************/
/* Video Loading TPL Block */
//var video_loader = new TransformManyBlock<string, Bitmap>(load_video, new ExecutionDataflowBlockOptions { BoundedCapacity = 10 });
var send_recv_block = new TransformBlock<Bitmap, Bitmap>(async recv_bitmap =>
{
Console.WriteLine("Inside send_recv block");
var mem_stream = new MemoryStream();
recv_bitmap.Save(mem_stream, System.Drawing.Imaging.ImageFormat.Jpeg);
var recv_image_array = mem_stream.ToArray();
NetworkStream stream = client.GetStream();
byte[] transmit_buffer = new byte[4];
transmit_buffer[0] = (byte)(recv_image_array.Length & (0xFF));
transmit_buffer[1] = (byte)((recv_image_array.Length >> 8) & (0xFF));
transmit_buffer[2] = (byte)((recv_image_array.Length >> 16) & (0xFF));
transmit_buffer[3] = (byte)((recv_image_array.Length >> 24) & (0xFF));
// Sending first the 32bit length
await stream.WriteAsync(transmit_buffer, 0, 4);
// Sending data
await stream.WriteAsync(recv_image_array, 0, recv_image_array.Length);
// Receiving data
var recv_buffer = await Receive(stream);
Bitmap tx_image_array;
using (var ms = new MemoryStream(recv_image_array))
{
tx_image_array = new Bitmap(ms);
}
return tx_image_array;
},
new ExecutionDataflowBlockOptions
{
//BoundedCapacity = 10,
CancellationToken = cancellationSource.Token
});
/****************** METHOD 2 - with send async ***********/
var video_loader = new ActionBlock<string>(async path =>
{
Console.WriteLine("video_loader");
capture = new VideoCapture(path);
Mat matrix = new Mat();
capture.Read(matrix);
var mem_stream = new MemoryStream();
while (matrix.Rows != 0 && matrix.Width != 0)
{
Console.WriteLine("Inside Loop");
capture.Read(matrix);
if (matrix.Rows == 0 && matrix.Width == 0) break;
Bitmap bitmap = new Bitmap(matrix.Width, matrix.Rows);
bitmap = matrix.ToBitmap();
await send_recv_block.SendAsync(bitmap);
await Task.Delay(20);
if (_canceller.Token.IsCancellationRequested) break;
}
}, new ExecutionDataflowBlockOptions
{
//BoundedCapacity = 10 ,
CancellationToken = cancellationSource.Token
});
/* Video Loading TPL Block */
var display_video = new ActionBlock<Bitmap>(async received_image =>
{
Console.WriteLine("Inside Display Video");
PicturePlot2.Image = received_image;
await Task.Delay(25);
},
new ExecutionDataflowBlockOptions()
{
TaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(),
//BoundedCapacity = 10,
CancellationToken = cancellationSource.Token
});
var linkOptions = new DataflowLinkOptions { PropagateCompletion = true };
/****************** METHOD 2 - with send async *************/
Console.WriteLine("to Link");
var send_recv_disposable = send_recv_block.LinkTo(display_video, linkOptions);
Console.WriteLine("Video path" + video_path);
//var apotelesma_post = video_loader.Post(video_path);
var apotelesma_post = await video_loader.SendAsync(video_path);
Console.WriteLine("Apotelesma Post "+ apotelesma_post);
video_loader.Complete();
try
{
await display_video.Completion;
}
catch (TaskCanceledException ex)
{
Console.WriteLine(ex.CancellationToken.IsCancellationRequested);
video_loader.Complete();
send_recv_block.Complete();
display_video.Complete();
MessageBox.Show("Video Ended");
}
}
private void Stop_Reset_Click(object sender, EventArgs e)
{
cancellationSource.Cancel();
_canceller.Cancel();
}
Thanks in Advance

You've not shown where you declare the variable cancellationSource, which you supply to the ExecutionDataFlowBlockOptions.
When you supply a cancellation token to the ExecutionDataFlowBlockOptions, you are telling the block to enter the Completed state with a task status of Canceled when the token is cancelled. The docs tell us this is final:
Because the CancellationToken property permanently cancels dataflow block execution, the whole pipeline must be recreated after the user cancels the operation and then wants to add more work items to the pipeline.[1]
Because your stop button sets this token to cancelled, when you recreate the blocks they are beginning in the cancelled state.
Above _canceller = new CancellationTokenSource(); you need to add cancellationSource = new CancellationTokenSource();.

Related

I am trying to use flutter Isolate with database data. But it's throwing an error. I don't know why is it happening?

I'm using the hive database. My code is:
HiveStocktaking? stocktaking =
_database.getStocktakingById(_stocktakingId);
StocktakingStats stocktakingStats =
_database.getStocktakingStats(_stocktakingId, true);
List<HiveStocktakingItem> stocktakingItemShortage = _database
.getStocktakingAllItem(_stocktakingId, 'shortage', '',
getAll: withProducts)
.values
.first;
List<HiveStocktakingItem> stocktakingItemSurplus = _database
.getStocktakingAllItem(_stocktakingId, 'surplus', '',
getAll: withProducts)
.values
.first;
int shortageLength = withProducts ? stocktakingItemShortage.length : 0;
int surplusLength = withProducts ? stocktakingItemSurplus.length : 0;
if (type == 'excel') {
createIsolate(
stocktaking,
stocktakingStats,
stocktakingItemShortage,
stocktakingItemSurplus,
shortageLength,
surplusLength,
);
}
Future createIsolate(
HiveStocktaking? stocktaking,
StocktakingStats stocktakingStats,
List<HiveStocktakingItem> stocktakingItemShortage,
List<HiveStocktakingItem> stocktakingItemSurplus,
int shortageLength,
int surplusLength) async {
ReceivePort receivePort = ReceivePort();
Isolate.spawn(isolateFunction, receivePort.sendPort);
SendPort childSendPort = await receivePort.first;
ReceivePort responsePort = ReceivePort();
childSendPort.send([
stocktaking,
stocktakingStats,
stocktakingItemShortage,
stocktakingItemSurplus,
shortageLength,
surplusLength,
responsePort.sendPort
]);
var sum = await responsePort.first;
print('sum: $sum');
}
void isolateFunction(SendPort mainSendPort) async {
ReceivePort childReceivePort = ReceivePort();
mainSendPort.send(childReceivePort.sendPort);
await for (var message in childReceivePort) {
HiveStocktaking? stocktaking = message[0];
StocktakingStats stocktakingStats = message[1];
List<HiveStocktakingItem> stocktakingItemShortage = message[2];
List<HiveStocktakingItem> stocktakingItemSurplus = message[3];
int shortageLength = message[4];
int surplusLength = message[5];
SendPort replyPort = message[6];
//heavy task
sync.Workbook workbook = sync.Workbook();
var sheet = workbook.worksheets[0];
sheet.getRangeByIndex(1, 1)
..setText('Отчет по инвентаризации')
..columnWidth = 40
..cellStyle.bold = true
..rowHeight = 30
..cellStyle.fontSize = 20;
sheet.getRangeByIndex(2, 1).setText('Магазин: ${stocktaking?.shopName}');
sheet
.getRangeByIndex(3, 1)
.setText('Дата начала: ${stocktaking?.createdAt}');
sheet
.getRangeByIndex(4, 1)
.setText('Дата завершения: ${stocktaking?.finishedAt}');
sheet.getRangeByIndex(2, 3)
..setText(
'Отсканировано товаров: ${BaseFunctions.numberRound(stocktakingStats.totalScannedMeasurementValue)}')
..columnWidth = 30;
sheet.getRangeByIndex(3, 3).setText(
'Недостач: ${BaseFunctions.numberRound(stocktakingStats.totalMeasurementValue)}');
sheet.getRangeByIndex(4, 3).setText(
'Излишков: ${BaseFunctions.numberRound(stocktakingStats.surplus)}');
// etc generating codes
List<int> bytes = workbook.saveAsStream();
workbook.dispose();
var uint8list = Uint8List.fromList(bytes);
if (Platform.isMacOS) {
String fileName = 'stocktaking_report_' +
DateFormat('dd-MM-yyyy_HH-mm-ss').format(DateTime.now()) +
'.pdf';
String? path =
await PathProviderPlatform.instance.getApplicationSupportPath();
final File file =
File(Platform.isWindows ? '$path\\$fileName' : '$path/$fileName');
await file.writeAsBytes(bytes, flush: true);
await Process.run('open', <String>['$path/$fileName'], runInShell: true);
} else {
await FileSaver.instance.saveFile(
'stocktaking_report_' +
DateFormat('dd-MM-yyyy_HH-mm-ss').format(DateTime.now()),
uint8list,
'xlsx',
mimeType: MimeType.MICROSOFTEXCEL,
);
}
replyPort.send(1);
}
}
But it is throwing this error:
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: (object extends NativeWrapper - Library:'dart:io' Class: _RandomAccessFileOpsImpl#13069316)
if I give the createIsolate fake data it works perfectly.
if (type == 'excel') {
ProjectFiles.createIsolate(
HiveStocktaking(),
StocktakingStats(),
[],
[],
0,
0,
);
}
I found a way to solve this issue. If you want to use the hive database in an isolate function note that you must init your database in the isolate function and close the boxes (which you want to use in the isolate) in the main thread. Register the boxes' adapter in the isolate. After your doing close the boxes which opened in isolate. To initiate the database in isolate, you have to set the database path to Hive.init(path). You can send this path through isolate's port. If you want to use closed boxes in the main thread you have to reopen it. Here some codes for example:
static Future<bool> myFunc() async {
ReceivePort receivePort = ReceivePort();
Isolate.spawn(isolateFunc, receivePort.sendPort);
SendPort childSendPort = await receivePort.first;
await Hive.box<YourBox>('boxName').close();
// database path
Directory appDocumentDir = await getApplicationDocumentsDirectory();
ReceivePort responsePort = ReceivePort();
childSendPort.send([appDocumentDir, responsePort.sendPort]);
var sum = await responsePort.first;
var box = await Hive.openBox<YourBox>('boxName');
HiveDatabase.setInstanceYourBox(box);
return sum == 1;
}
static void isolateDownloadStocktaking(SendPort mainSendPort) async {
ReceivePort childReceivePort = ReceivePort();
mainSendPort.send(childReceivePort.sendPort);
await for (var message in childReceivePort) {
Directory appDocumentDir = message[0];
Hive.init(appDocumentDir.path);
Hive.registerAdapter(YourBoxAdapter());
await HiveDatabase.getInstanceYourBox();
// you can use your box
SendPort replyPort = message[1];
await Hive.box<YourBox>('boxName').close();
replyPort.send(1);
}
}
HiveDatabase class is here:
class HiveDatabase {
static Box<YourBox>? _yourBox;
static HiveDatabase instance = HiveDatabase._();
HiveDatabase._();
static Future<HiveDatabase> getInstanceYourBox() async {
_yourBox ??= await Hive.openBox<YourBox>('boxName');
return instance;
}
static Future<HiveDatabase> setInstanceYourBox(Box<YourBox> box) async {
_yourBox = box;
return instance;
}
List<YourBox> elements() {
return (_yourBox?.values ?? []).toList();
}
Future<void> updateElement(YourBox value) async {
await _yourBox?.put(value.id, value);
}
Future<void> addElement(YourBox value) async {
await _yourBox?.put(value.id, value);
}
Future<void> deleteElement(int index) async {
await _yourBox?.deleteAt(index);
}
Future<void> clearYourBox() async {
await _yourBox?.clear();
}
}

Making a button visible after its past the current time using Xamarin.Forms

I have a list-view which displays the current user medication schedule it currently sorts the list by the next due date and any medications that are past the current time are moved to the bottom of the list.
I was looking to make the medications that are past the current time to have a 'Tomorrow' button visible to it. Is this possible to do?
Currently this is how I am populating my listview:
/// <summary>
/// Gets User Medication list
/// </summary>
/// <returns>The user meds.</returns>
async public Task GetUserMedsOverdue()
{
MedicationListOverdue.ItemsSource = null;
UserMedTimesOverdue.Clear(); //Clears the list before calling API (prevents duplication)
main.Children.Add(MedicationListOverdue);
main.Children.Remove(NoMeds);
if (!CrossConnectivity.Current.IsConnected)
{
main.Children.Remove(MedicationListOverdue);
main.Children.Add(NoMeds);
NoMeds.Text = "No Internet Connection - Please check your connection";
NoMeds.Margin = new Thickness(35, 35, 20, 20);
BusyIndicator.IsRunning = false;
}
else
{
BusyIndicator.IsRunning = true;
//var usermed = await medicinemanager.CurrentClient.InvokeApiAsync<IEnumerable<usermedication>>("getusermednamejoin?userid=" + Helpers.Settings.UserKey + "", System.Net.Http.HttpMethod.Get, null);
try
{
var usermeddosagetimeoverdue = await medicinemanager.CurrentClient.InvokeApiAsync("getUserMedDosageTimeOverdue?userid=" + Helpers.Settings.UserKey, null, HttpMethod.Get, await App.LoadAPIKeyAsync(), null);
var responseContentoverdue = await usermeddosagetimeoverdue.Content.ReadAsStringAsync();
var useroverdue = JsonConvert.DeserializeObject<ObservableCollection<UserMedDosagePayLoadOverdue>>(responseContentoverdue);
//var usermeddosagetime = await medicinemanager.CurrentClient.InvokeApiAsync<IEnumerable<UserMedDosagePayLoad>>("getusermeddosagetime?userid=" + Helpers.Settings.UserKey + "", HttpMethod.Get, API, System.Threading.CancellationToken.None);
//null, System.Net.Http.HttpMethod.Get, API, System.Threading.CancellationToken.None);
Debug.WriteLine("UserMedDosageTime" + usermeddosagetimeoverdue);
foreach (UserMedDosagePayLoadOverdue item in useroverdue)
{
UserMedTimesOverdue.Add(item);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
}
FindNextDue(UserMedTimes);
//Get the List of meds the user is on
//UserMedList = await usermedicationmanager.getUserMedication();
//foreach (usermedication item in usermed)
//{
// if (item.IsActive != false)
// {
// UserMedList.Add(item);
// }
//}
if (UserMedTimes.Count != 0)
{
MedicationListOverdue.ItemsSource = UserMedTimesOverdue;
BusyIndicator.IsRunning = false;
}
else
{
Label MedLogo = new Label();
MedLogo.Text = peoplewithfonticon.meds;
MedLogo.FontFamily = "icomoon";
MedLogo.FontSize = 80;
MedLogo.Margin = new Thickness(30, 80, 0, 0);
Label MedTitle = new Label();
MedTitle.Text = "No \r\nMedications";
MedTitle.FontSize = 50;
MedTitle.FontAttributes = FontAttributes.Bold;
MedTitle.Margin = new Thickness(30, 0, 0, 0);
Label NoMeds = new Label();
NoMeds.Margin = new Thickness(30, 0, 0, 0);
main.Children.Remove(MedicationList);
//main.Children.Remove(btnHistory);
main.Children.Add(MedLogo);
main.Children.Add(MedTitle);
main.Children.Add(NoMeds);
NoMeds.Text = "You haven't added any medications to your medication cupboard yet";
//main.Children.Add(btnHistory);
BusyIndicator.IsRunning = false;
}
MedicationListOverdue.ItemsSource = UserMedTimesOverdue;
BusyIndicator.IsRunning = false;
}
}
//Order the collection of times so the next due is always first
TimeComparison = new List<TimeSpan>(TimeComparison.OrderBy(h => h.Hours).ThenBy(m => m.Minutes));
List<string> UserMedIDs = new List<string>();
for (int i = 0; i < TimeComparison.Count(); i++)
{
DateTime NextDue = DateTime.Now.Add(TimeComparison[i]);
DateTime NextDueToCompare = new DateTime(NextDue.Year, NextDue.Month, NextDue.Day, NextDue.Hour, NextDue.Minute, 0);
string NextDueComparisonString = NextDueToCompare.ToString("HH:mm:ss");
foreach (UserMedDosagePayLoad item in UserMedTimes)
{
if (item.Time == NextDueComparisonString && !UserMedIDs.Contains(item.Usermedid))
{
UserMedTimesFilteredList.Add(item);
UserMedIDs.Add(item.Usermedid);
}
}
UserMedTimes = medtimes;
MedicationList.ItemsSource = UserMedTimesFilteredList.OrderBy(X => NextDue);
BusyIndicator.IsRunning = false;
}

Response status code does not indicate success: '400' ('Bad request')

i want to POST data to API in my android xamarin app using refit i've tested the API at Postman and it's working fine but at android app i'm getting exception Bad request.
Here is my android code i added the interface and the model i don't know what is the problem .
public interface RequestAPI
{
[Post("/request")]
Task<create_request> submit([Body] create_request request);
}
requestAPI= RestService.For<RequestAPI>("http://courier-magconsulting.azurewebsites.net/api");
button.Click += async delegate
{
try
{
create_request request = new create_request();
request.PickUpPhone = "7664554";
request.DownPayment = 89;
request.DeliveryFees = 56.8;
request.Note = "i need a help!";
request.RequestID = 88; // replace the value yourself
request.DekiveryLocationLatitude = 2323;
request.DeliveryLocationLongitude = 232;
request.PickUpLocationLatitude = 898;
request.PickUpLocationLongitude = 1123;
BroadcastType type = new BroadcastType();
type.Name = "All";
type.ID = 60; // replace the value yourself
request.BroadcastType = type;
Cargosize size = new Cargosize();
size.Name = "Small";
size.ID = 1; // replace the value yourself
request.Cargosize = size;
Cargoweight weight = new Cargoweight();
weight.Name = "Large";
weight.ID = 2; // replace the value yourself
request.CargoWeight = weight;
Sender sender_ = new Sender();
sender_.Name = "Ahmad";
sender_.SenderID = 1; // replace the value yourself
sender_.Phone = "8788";
sender_.SocialID = "8787";
sender_.RatingAvg = 5;
SenderStatus status = new SenderStatus();
status.ID = 1;
status.Name = "Active";
sender_.Senderstatus = status;
request.Sender = sender_;
create_request result = await requestAPI.submit(request);
Toast.MakeText(this, "Request created", ToastLength.Long).Show();
}
catch(Exception ex)
{
Toast.MakeText(this, ex.Message, ToastLength.Long).Show();
}
};

How do you create a client using websocket-sharp?

I'm using ClientWebSocket to subscribe to a REST service but want to be able to use websocket-sharp instead.
static async void MonitorISY(string IPAddress, string userName, string password, IMessageWriter writer)
{
ClientWebSocket client = new ClientWebSocket();
client.Options.AddSubProtocol("ISYSUB");
client.Options.SetRequestHeader("Origin", "com.universal-devices.websockets.isy");
var auth = Convert.ToBase64String(Encoding.Default.GetBytes(userName + ":" + password));
client.Options.SetRequestHeader("Authorization", "Basic " + auth);
await client.ConnectAsync(new Uri("ws://" + IPAddress + "/rest/subscribe"), CancellationToken.None);
var receiveBufferSize = 512;
byte[] buffer = new byte[receiveBufferSize];
writer.Clear();
while (true)
{
var result = await client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
var resultJson = (new UTF8Encoding()).GetString(buffer);
writer.WriteLn(resultJson);
writer.WriteLn();
}
}
Here is my websocket-sharp attempt. When ws.Connect(); is called, I'm getting a Not a WebSocket handshake response error message. In the working code, I have to setup the Origin, SubProtocol and the RequestHeader. I think I'm doing that correctly for the websocket-sharp code, with the exception of the Request Header. I've been unable to find a working example that specifies authentication.
using (var nf = new Notifier())
using (var ws = new WebSocket("ws://172.16.0.40/rest/subscribe", "ISYSUB"))
{
ws.Log.Level = LogLevel.Trace;
var username = "user";
var password = "pass";
ws.Origin = "com.universal-devices.websockets.isy";
ws.SetCredentials(username, password, true);
ws.OnOpen += (sender, e) => ws.Send("Hi, there!");
ws.OnMessage += (sender, e) =>
nf.Notify(
new NotificationMessage
{
Summary = "WebSocket Message",
Body = !e.IsPing ? e.Data : "Received a ping.",
Icon = "notification-message-im"
}
);
ws.OnError += (sender, e) =>
nf.Notify(
new NotificationMessage
{
Summary = "WebSocket Error",
Body = e.Message,
Icon = "notification-message-im"
}
);
ws.OnClose += (sender, e) =>
nf.Notify(
new NotificationMessage
{
Summary = String.Format("WebSocket Close ({0})", e.Code),
Body = e.Reason,
Icon = "notification-message-im"
}
);
ws.Connect();
I think the best example is https://github.com/sta/websocket-sharp/tree/master/Example3
Although I did have to make a few tiny adjustments to get it to compile in Visual Studio 2017 Enterprise.
The index.html is based on http://www.websocket.org/echo.html

Async and Await didn't work on web api

I am trying to use await on my async method but it didn't work. I input 2 array of parameters when calling the post method, only the last one is inserted
to database(I use Elasticsearch as database so when the _id is the same the document will replaced by the new one). and I found out when insert is not done yet the program is already run to query the database and the result is 0 so it's insert again instead of update.
I already add await on my program but it didn't work out. Can anyone help me with this problem? Thanks
here is my code
// POST api/values
[HttpPost]
public async Task<AvatarModel.AvatarResponse> Post(MultiLanguageTemp[] LangTemp)
{
//process param to multilanguage model
AvatarModel.AvatarResponse Resp = new AvatarModel.AvatarResponse();
try
{
for (int i = 0; i < LangTemp.Length; i++)
{
string Type = LangTemp[i].Type;
if ("ErrorCode".Equals(Type))
{
}
else
{
string GetLabelId = LangTemp[i].LabelId;
string GetTranslation = LangTemp[i].Translation;
MultiLanguage Lang = new MultiLanguage();
Lang.Type = LangTemp[i].Type;
Lang.Site = LangTemp[i].Site;
Lang.Language = LangTemp[i].LangId;
Lang.Source = LangTemp[i].Source;
Lang.TranslationList = new Dictionary<string, string>();
Lang.TranslationList.Clear();
Lang.TranslationList.Add(GetLabelId, GetTranslation);
//search elasticsearch first using id TYPE+SITE+LANG_ID+SOURCE
string ESResponse = await GetMultiLangAsync(Lang);
JObject GetResp = JObject.Parse(ESResponse);
//get elasticsearch Hits count
JToken GetHitsTotal = GetResp.SelectToken("hits.total");
int Hits = int.Parse(GetHitsTotal.ToString());
// if id exist then do update else do insert
if (Hits > 0)
{
string ResponseUpdate = await UpdateMultiLangAsync(GetLabelId, GetTranslation,Lang);
if (!ResponseUpdate.ToString().ToUpper().Contains("ERROR"))
{
Resp.Result = "0000000";
Resp.Message = "Update MultiLanguage Info is Success";
}
else
{
Resp.Result = "9000003";
Resp.Message = "Update MultiLanguage Info into ES failed";
}
}
else
{
//tasks.Add(InsertMultiLangAsync(Lang));
//insert new document into elasticsearch
string InsertESResponse = await InsertMultiLangAsync(Lang);
if (!InsertESResponse.ToUpper().Contains("ERROR"))
{
Resp.Result = "0000000";
Resp.Message = "Insert MultiLanguage Info is Success";
}
else
{
Resp.Result = "9000003";
Resp.Message = "Insert MultiLanguage Info into ES failed";
}
}
}
}
}
catch (Exception E)
{
Resp.Result = "9000005";
Resp.Message = E.Message.ToString();
}
return Resp;
}
public async Task<string> GetMultiLangAsync(MultiLanguage Lang)
{
var Client = new HttpClient();
Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/MultiLangInfo/");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var Query = "{\"query\": {\"match\": {\"_id\":\"" + Lang.Type + Lang.Site + Lang.Language + Lang.Source + "\"}}}";
var StringContent = new StringContent(Query, Encoding.UTF8, "application/json");
var Response = Client.PostAsync("_search", StringContent).Result.Content.ReadAsStringAsync();
//JObject GetResp = JObject.Parse(Response.Result);
return await Response;
}
public async Task<string> InsertMultiLangAsync(MultiLanguage Lang)
{
var Client = new HttpClient();
Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var JsonTextMultiLang = JsonConvert.SerializeObject(Lang, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var StringContent = new StringContent(JsonTextMultiLang, Encoding.UTF8, "application/json");
var ResponseInsert = Client.PostAsync("MultiLangInfo/" + Lang.Type + Lang.Site + Lang.Language + Lang.Source, StringContent).Result.Content.ReadAsStringAsync();
return await ResponseInsert;
}
public async Task<string> UpdateMultiLangAsync(string GetLabelId,string GetTranslation, MultiLanguage Lang)
{
var UpdateES = "{\"doc\":{\"TranslationList\":{\"" + GetLabelId + "\":\"" + GetTranslation + "\"}},\"detect_noop\":true}";
var Client = new HttpClient();
Client.BaseAddress = new Uri("http://localhost:9200/multilanguage/MultiLangInfo/" + Lang.Type + Lang.Site + Lang.Language + Lang.Source + "/");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var StringContent = new StringContent(UpdateES, Encoding.UTF8, "application/json");
var ResponseUpdate = Client.PostAsync("_update", StringContent).Result.Content.ReadAsStringAsync();
return await ResponseUpdate;
}
Here is my insight.
Based on the details you provided, you have a long-running task that would eventually create/update a record in your database. Now, the problem you encounter is the second http request you send is not waiting for the first one to finish even though you are using async/await pattern. Well, this is not how it works. Regardless of what you do, whether you block the thread or not, there is thread pooling and distinct http calls will have their own thread. So using async/await would not affect that at all. For the most part, you're using async/await correctly. However, what you're trying to achieve is not done by async/await. You might want to try a messaging system to queue all the requests. In that case, you can't put clients on hold, You'd generate a request id and send it to them immediately and process the request asynchronously in time.

Resources