This is Task Code
public async Task Demo(int row_index, CancellationToken token)
{
Task t1 = Task.Run(() =>
{
ChromeOptions chromeOptions = new ChromeOptions();
ChromeDriverService chromeDriverService = ChromeDriverService.CreateDefaultService();
chromeDriverService.SuppressInitialDiagnosticInformation = true;
chromeDriverService.HideCommandPromptWindow = true;
this.chrome[row_index] = new ChromeDriver(chromeDriverService, chromeOptions);
this.chrome[row_index].Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(59.0);
Dologin(row_index);
//Lay Ten Fb
chrome[row_index].Url = "https://facebook.com/profile";
var conchim = chrome[row_index].FindElementByCssSelector("#fb-timeline-cover-name > a");
this.dataGridView1.Rows[row_index].Cells["trangthai"].Value = "Tiến Hành Lấy Tên Facebook";
foreach (DataGridViewRow r in dataGridView1.Rows)
{
string value1 = r.Cells[0].Value.ToString() ?? string.Empty;
if (value1 == tkfacebook)
{
r.Cells[4].Value = conchim.Text;
break;
}
}
},token);
}
This is Code Run Task And Cancel Task.
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token;
public async void HandleValue(DataGridViewCell cell, int row_index)
{
switch (cell.Value.ToString())
{
case "Bắt đầu":
bool flag7 = Convert.ToInt32(this.txtClickStart.Value) > Convert.ToInt32(this.txtClickEnd.Value);
if (radioButton1.Checked && !flag7)
{
cell.Value = "Kết Thúc";
token = source.Token;
await Demo(row_index,token);
}
if (flag7)
{
this.dataGridView1.Rows[row_index].Cells["trangthai"].Value = "Cài đặt thời gian không đúng";
MessageBox.Show(new Form
{
TopMost = true
}, "Cài đặt thời gian không đúng, hãy cài đặt lại!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return;
}
bool flag3 = !radioButton1.Checked || !radioButton1.Checked && !radioButton2.Checked;
if (flag3)
{
MessageBox.Show("Vui Lòng Chọn Trình Duyệt Để Bắt Đầu Chạy");
}
break;
case "Kết Thúc":
source.Cancel();
chrome[row_index].Quit();
cell.Value = "Bắt đầu";
this.dataGridView1.Rows[row_index].Cells["trangthai"].Value = "Bạn đã chọn kết thúc làm việc";
break;
}
}
Thread is not working so i do Task . But it still Run when i already Do Task Cancel. ...............
source.Cancel();
Make Post Longger to Avablie To Post . Dont Care this Rows ..dfsdfsdfsddfsddsadasdsadasdsadasdasdassdasdasdasdasdasdasdasdasdasdadda
If you aim to cancel the execution of logic, then you need to check IsCancellationRequested flag.
while(!token.IsCancellationRequested)
{
//whatever logic you want run should be placed here. This logic won't be
//executed after you call Cancel()
}
Above logic will continue to execute your logic until you called Cancel() on token source. You can find some example 1 and 2.
Your Code for Demo should include a check on the cancelation-Token. Try something like this:
Task t1 = Task.Run(() =>
{
ChromeOptions chromeOptions = new ChromeOptions();
ChromeDriverService chromeDriverService = ChromeDriverService.CreateDefaultService();
chromeDriverService.SuppressInitialDiagnosticInformation = true;
chromeDriverService.HideCommandPromptWindow = true;
this.chrome[row_index] = new ChromeDriver(chromeDriverService, chromeOptions);
this.chrome[row_index].Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(59.0);
Dologin(row_index);
//Lay Ten Fb
chrome[row_index].Url = "https://facebook.com/profile";
var conchim = chrome[row_index].FindElementByCssSelector("#fb-timeline-cover-name > a");
this.dataGridView1.Rows[row_index].Cells["trangthai"].Value = "Tiến Hành Lấy Tên Facebook";
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Task was cancelled by user.");
token.ThrowIfCancellationRequested();
}
string value1 = r.Cells[0].Value.ToString() ?? string.Empty;
if (value1 == tkfacebook)
{
r.Cells[4].Value = conchim.Text;
break;
}
}
},token);
Please also refer the example here:
https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken.iscancellationrequested?view=netframework-4.8
Related
I am trying get the Job state but Task is not finishing as it is going to the else polling block
Please can anyone guide me i am unablet to figure it out
This is what i hava tried
#region Job Status Action
EventProcessorClient processorClient = null;
BlobContainerClient storageClient = null;
MediaServicesEventProcessor mediaEventProcessor = null;
//log.LogInformation($"Job '{jobName}' submitted.");
try
{
Console.WriteLine("Creating a new client to process events from an Event Hub...");
var credential = new DefaultAzureCredential();
var EventHubConnectionString = "Endpoint=sb://komurojusaikrishn.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=<Shared Access key>";
//var storageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
// config.AccountName, config.StorageAccountKey);
var storageConnectionString = string.Format("DefaultEndpointsProtocol=https;AccountName=<Account Name>;AccountKey=<Account key>;EndpointSuffix=core.windows.net");
var blobContainerName = "asset-fcc961b8-cc25-4f4f-8617-9c767d865572";//"blob-01182023";//config.StorageContainerName;
var eventHubsConnectionString = EventHubConnectionString;
var eventHubName = "<Event Hub Name>";
var consumerGroup = "$Default";//config.EventHubConsumerGroup;
storageClient = new BlobContainerClient(
storageConnectionString,
blobContainerName);
processorClient = new EventProcessorClient(
storageClient,
consumerGroup,
eventHubsConnectionString, eventHubName);
AutoResetEvent jobWaitingEvent = new AutoResetEvent(false);
IList<Task> tasks = new List<Task>();
Task jobTask = Task.Run(() =>
jobWaitingEvent.WaitOne());
tasks.Add(jobTask);
// 30 minutes timeout.
var cancellationSource = new CancellationTokenSource();
var timeout = Task.Delay(5 * 60 * 1000, cancellationSource.Token);
tasks.Add(timeout);
mediaEventProcessor = new MediaServicesEventProcessor(jobName, jobWaitingEvent, null);
processorClient.ProcessEventAsync += mediaEventProcessor.ProcessEventsAsync;
processorClient.ProcessErrorAsync += mediaEventProcessor.ProcessErrorAsync;
await processorClient.StartProcessingAsync(cancellationSource.Token);
//**Here the condition is failing always because jobTask is not completed and** //**going to the else block**
if (await Task.WhenAny(tasks) == jobTask)
{
cancellationSource.Cancel();
job = await client.Jobs.GetAsync(config.ResourceGroup, config.AccountName, ObjReqconfig.TransformName, jobName);
}
else
{
jobWaitingEvent.Set();
throw new Exception("Timeout occurred.");
}
}
catch (Exception e)
{
Console.WriteLine("Warning: Failed to connect to Event Hub, please refer README for Event Hub and storage settings.");
Console.WriteLine(e.Message);
Console.WriteLine("Polling job status...");
job = await JobStatusChecker.WaitForJobToFinishAsync(client, config.ResourceGroup, config.AccountName, ObjReqconfig.TransformName, jobName);
}
finally
{
if (processorClient != null)
{
Console.WriteLine("Job final state received, Stopping the event processor...");
await processorClient.StopProcessingAsync();
Console.WriteLine();
processorClient.ProcessEventAsync -= mediaEventProcessor.ProcessEventsAsync;
processorClient.ProcessErrorAsync -= mediaEventProcessor.ProcessErrorAsync;
}
}
#endregion
//TimeSpan elapsed = DateTime.Now - startedTime;
MediaServicesEventProcessor.cs :
public class MediaServicesEventProcessor
{
private readonly AutoResetEvent jobWaitingEvent;
private readonly string jobName;
private readonly string liveEventName;
public MediaServicesEventProcessor(string jobName, AutoResetEvent jobWaitingEvent, string liveEventName)
{
this.jobName = jobName;
this.jobWaitingEvent = jobWaitingEvent;
this.liveEventName = liveEventName;
}
public Task ProcessErrorAsync(ProcessErrorEventArgs args)
{
try
{
Console.WriteLine("Error in the EventProcessorClient");
Console.WriteLine($"\tOperation: { args.Operation }");
Console.WriteLine($"\tException: { args.Exception }");
Console.WriteLine("");
}
catch
{
}
return Task.CompletedTask;
}
public Task ProcessEventsAsync(ProcessEventArgs args)
{
if (args.HasEvent)
{
PrintJobEvent(args.Data);
}
return args.UpdateCheckpointAsync();
}
private void PrintJobEvent(Azure.Messaging.EventHubs.EventData eventData)
{
// data = Encoding.UTF8.GetString(eventData.EventBody);
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
//EventGridEvent[] egEvents
var jsonArray = JsonSerializer.Deserialize<EventGridEvent[]>(eventData.EventBody.ToString(), options);
//foreach (Azure.Messaging.EventGrid.EventGridEvent e in jsonArray)
foreach (EventGridEvent e in jsonArray)
{
var subject = e.Subject;
var topic = e.Topic;
var eventType = e.EventType;
var eventTime = e.EventTime;
string eventSourceName = Regex.Replace(subject, #"^.*/", "");
if (eventSourceName != jobName && eventSourceName != liveEventName)
{
return;
}
// Log the time and type of event
Console.WriteLine($"{eventTime} EventType: {eventType}");
switch (eventType)
{
// Job state change events
case "Microsoft.Media.JobStateChange":
case "Microsoft.Media.JobScheduled":
case "Microsoft.Media.JobProcessing":
case "Microsoft.Media.JobCanceling":
case "Microsoft.Media.JobFinished":
case "Microsoft.Media.JobCanceled":
case "Microsoft.Media.JobErrored":
{
MediaJobStateChangeEventData jobEventData = JsonSerializer.Deserialize<MediaJobStateChangeEventData>(e.Data.ToString(), options);
Console.WriteLine($"Job state changed for JobId: {eventSourceName} PreviousState: {jobEventData.PreviousState} State: {jobEventData.State}");
// For final states, send a message to notify that the job has finished.
if (eventType == "Microsoft.Media.JobFinished" || eventType == "Microsoft.Media.JobCanceled" || eventType == "Microsoft.Media.JobErrored")
{
// Job finished, send a message.
if (jobWaitingEvent != null)
{
jobWaitingEvent.Set();
}
}
}
break;
// Job output state change events
case "Microsoft.Media.JobOutputStateChange":
case "Microsoft.Media.JobOutputScheduled":
case "Microsoft.Media.JobOutputProcessing":
case "Microsoft.Media.JobOutputCanceling":
case "Microsoft.Media.JobOutputFinished":
case "Microsoft.Media.JobOutputCanceled":
case "Microsoft.Media.JobOutputErrored":
{
MediaJobOutputStateChangeEventData jobEventData = JsonSerializer.Deserialize<MediaJobOutputStateChangeEventData>(e.Data.ToString(), options);
Console.WriteLine($"Job output state changed for JobId: {eventSourceName} PreviousState: {jobEventData.PreviousState} " +
$"State: {jobEventData.Output.State} Progress: {jobEventData.Output.Progress}%");
}
break;
// Job output progress event
case "Microsoft.Media.JobOutputProgress":
{
MediaJobOutputProgressEventData jobEventData = JsonSerializer.Deserialize<MediaJobOutputProgressEventData>(e.Data.ToString(), options);
Console.WriteLine($"Job output progress changed for JobId: {eventSourceName} Progress: {jobEventData.Progress}%");
}
break;
// LiveEvent Stream-level events
// See the following documentation for updated schemas - https://docs.microsoft.com/azure/media-services/latest/monitoring/media-services-event-schemas#live-event-types
case "Microsoft.Media.LiveEventConnectionRejected":
{
MediaLiveEventConnectionRejectedEventData liveEventData = JsonSerializer.Deserialize<MediaLiveEventConnectionRejectedEventData>(e.Data.ToString(), options);
Console.WriteLine($"LiveEvent connection rejected. IngestUrl: {liveEventData.IngestUrl} StreamId: {liveEventData.StreamId} " +
$"EncoderIp: {liveEventData.EncoderIp} EncoderPort: {liveEventData.EncoderPort}");
}
break;
case "Microsoft.Media.LiveEventEncoderConnected":
{
MediaLiveEventEncoderConnectedEventData liveEventData = JsonSerializer.Deserialize<MediaLiveEventEncoderConnectedEventData>(e.Data.ToString(), options);
Console.WriteLine($"LiveEvent encoder connected. IngestUrl: {liveEventData.IngestUrl} StreamId: {liveEventData.StreamId} " +
$"EncoderIp: {liveEventData.EncoderIp} EncoderPort: {liveEventData.EncoderPort}");
}
break;
case "Microsoft.Media.LiveEventEncoderDisconnected":
{
MediaLiveEventEncoderDisconnectedEventData liveEventData = JsonSerializer.Deserialize<MediaLiveEventEncoderDisconnectedEventData>(e.Data.ToString(), options);
Console.WriteLine($"LiveEvent encoder disconnected. IngestUrl: {liveEventData.IngestUrl} StreamId: {liveEventData.StreamId} " +
$"EncoderIp: {liveEventData.EncoderIp} EncoderPort: {liveEventData.EncoderPort}");
}
break;
case "Microsoft.Media.LiveEventIncomingDataChunkDropped":
{
MediaLiveEventIncomingDataChunkDroppedEventData liveEventData = JsonSerializer.Deserialize<MediaLiveEventIncomingDataChunkDroppedEventData>(e.Data.ToString(), options);
Console.WriteLine($"LiveEvent data chunk dropped. LiveEventId: {eventSourceName} ResultCode: {liveEventData.ResultCode}");
}
break;
case "Microsoft.Media.LiveEventIncomingStreamReceived":
{
MediaLiveEventIncomingStreamReceivedEventData liveEventData = JsonSerializer.Deserialize<MediaLiveEventIncomingStreamReceivedEventData>(e.Data.ToString(), options);
Console.WriteLine($"LiveEvent incoming stream received. IngestUrl: {liveEventData.IngestUrl} EncoderIp: {liveEventData.EncoderIp} " +
$"EncoderPort: {liveEventData.EncoderPort}");
}
break;
case "Microsoft.Media.LiveEventIncomingStreamsOutOfSync":
{
//MediaLiveEventIncomingStreamsOutOfSyncEventData eventData = JsonSerializer.Deserialize<MediaLiveEventIncomingStreamsOutOfSyncEventData>(e.Data.ToString(), options);;
Console.WriteLine($"LiveEvent incoming audio and video streams are out of sync. LiveEventId: {eventSourceName}");
}
break;
case "Microsoft.Media.LiveEventIncomingVideoStreamsOutOfSync":
{
//MediaLiveEventIncomingVideoStreamsOutOfSyncEventData eventData =JsonSerializer.Deserialize<MediaLiveEventIncomingVideoStreamsOutOfSyncEventData>(e.Data.ToString(), options);;
Console.WriteLine($"LeveEvent incoming video streams are out of sync. LiveEventId: {eventSourceName}");
}
break;
case "Microsoft.Media.LiveEventIngestHeartbeat":
{
MediaLiveEventIngestHeartbeatEventData liveEventData = JsonSerializer.Deserialize<MediaLiveEventIngestHeartbeatEventData>(e.Data.ToString(), options);
Console.WriteLine($"LiveEvent ingest heart beat. TrackType: {liveEventData.TrackType} State: {liveEventData.State} Healthy: {liveEventData.Healthy}");
}
break;
case "Microsoft.Media.LiveEventTrackDiscontinuityDetected":
{
MediaLiveEventTrackDiscontinuityDetectedEventData liveEventData = JsonSerializer.Deserialize<MediaLiveEventTrackDiscontinuityDetectedEventData>(e.Data.ToString(), options);
Console.WriteLine($"LiveEvent discontinuity in the incoming track detected. LiveEventId: {eventSourceName} TrackType: {liveEventData.TrackType} " +
$"Discontinuity gap: {liveEventData.DiscontinuityGap}");
}
break;
case "Microsoft.Media.LiveEventChannelArchiveHeartbeatEvent":
{
Console.WriteLine($"LiveEvent archive heartbeat event detected. LiveEventId: {eventSourceName}");
Console.WriteLine(e.Data.ToString());
}
break;
}
}
}
}
Please help me what i have missed
Additonal query : in the above code do i need to create separate blobContainer or do i have to use the same container which i used for the inputAsset creation
I need some help with Discord.Net. I have the following command written down:
[Command("project", RunMode=RunMode.Async)]
public async Task Project(string action, string id="")
{
switch(action)
{
case "post":
{
StringCreator tagger = new StringCreator();
string index = tagger.Get(5);
var project=await Context.Guild.CreateTextChannelAsync("project-id-" + index);
var message = await project.SendMessageAsync("What language is this project in?");
var rMessage = message.Id;
await message.AddReactionAsync(new Emoji("🇬🇧"));
await message.AddReactionAsync(new Emoji("🇮🇱"));
await message.AddReactionAsync(new Emoji("🇷🇴"));
break;
}
}
Now I tried making an event like this:
public async Task OnReactionAddedEvent(SocketReaction reaction)
{
if (reaction.Emote.Name == "🇬🇧")
{
vars.projectLang = "English";
}
if (reaction.Emote.Name == "🇮🇱")
{
vars.projectLang = "Hebrew";
}
if (reaction.Emote.Name == "🇷🇴")
{
vars.projectLang = "Romanian";
}
}
If I try to use it like this, just before the break in my command function:
_discord.ReactionAdded += OnReactionAddedEvent;
I tried editing my Event Method to take the marameter as cacheable but with no luck:
public async Task OnReactionAddedEvent(Cacheable<SocketReaction> reaction)
{
if (reaction.Emote.Name == "🇬🇧")
{
vars.projectLang = "English";
}
if (reaction.Emote.Name == "🇮🇱")
{
vars.projectLang = "Hebrew";
}
if (reaction.Emote.Name == "🇷🇴")
{
vars.projectLang = "Romanian";
}
}
Whatever I do, when declaring it in the command method, the whole statement shows up as an error. I'm at a loss, please help. Thank you in advance!
I have created a task which creates an XML string. The task can last multiple seconds. When the task isn't finished after 5 seconds, I want to cancel the Task 'smootly' and continue with writing the rest of the XML. So I built in cancellation inside my task. But although I see the following message in the Log:
ProcessInformationTask timed out
I also see this line in my log
Adding the process information took 10001 ms
I wonder why this can happen because I want to cancel the Task after 5 seconds (if not finished). So I expect the task to last 5 seconds max. How can I solve this? Probably the cancelation isn't setup properly?
Code where I call my task
string additionalInformation = null;
var contextInfo = new StringBuilder();
var xmlWriterSettings = new XmlWriterSettings()
{
OmitXmlDeclaration = true,
ConformanceLevel = ConformanceLevel.Fragment
};
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
using (XmlWriter xmlWriter = XmlWriter.Create(contextInfo, xmlWriterSettings))
{
try
{
xmlWriter.WriteStartElement("AdditionalInformation");
//Write xml (not long running)
var watch = System.Diagnostics.Stopwatch.StartNew();
string processInformation = AddProcessesInformation(xmlWriterSettings);
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;
Log.Info("Adding the process information took : " + elapsedMs + " ms");
if (!string.IsNullOrEmpty(processInformation))
{
xmlWriter.WriteRaw(processInformation);
}
//Write xml (not long running)
xmlWriter.WriteEndElement();
additionalInformation = contextInfo.ToString();
}
catch (Exception e)
{
Log.Info("An exception occured during writing the additional information: " + e.Message);
return false;
}
return true;
}
Task method
private static string AddProcessesInformation(XmlWriterSettings xmlWriterSettings)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var contextInfo = new StringBuilder();
var processInformationTask = Task<string>.Factory.StartNew(() =>
{
if (token.IsCancellationRequested)
{
Log.Info("Cancellation request for the ProcessInformationTask");
}
Thread.Sleep(10000);
return "Ran without problems'";
}, token);
if (!processInformationTask.Wait(5000, token))
{
Log.Info("ProcessInformationTask timed out");
tokenSource.Cancel();
}
return processInformationTask?.Result;
}
I think you should check if cancellation is requested multiple Times, after each step in your method. Here is example using for loop:
private static string AddProcessesInformation(XmlWriterSettings xmlWriterSettings)
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var contextInfo = new StringBuilder();
var processInformationTask = Task<string>.Factory.StartNew(() =>
{
for(int i = 0; i < 10; i++)
{
if (token.IsCancellationRequested)
{
Console.WriteLine("Cancellation request for the ProcessInformationTask");
return string.Empty;
}
Thread.Sleep(1000);
}
return "Ran without problems'";
}, token);
if (!processInformationTask.Wait(5000, token))
{
Console.WriteLine("ProcessInformationTask timed out");
tokenSource.Cancel();
}
return processInformationTask?.Result;
}
If inside task method you call other methods, you can pass cancellation token to them and use method token.ThrowIfCancellationRequested() inside.
var processInformationTask = Task<string>.Factory.StartNew(() =>
{
try
{
Method1(token);
Thread.Sleep(1000);
Method2(token);
Thread.Sleep(1000);
}
catch(OperationCanceledException ex)
{
return string.Empty;
}
return "Ran without problems'";
}, token);
private static void Method1(CancellationToken token)
{
token.ThrowIfCancellationRequested();
// do more work
}
I have a ImageProcessor class that creates a list of tasks for each of the image providers, inside of these tasks I then run a parallel.foreach loop for all the images for each provider, I want to be able to cancel all the tasks and nested parallel loops from the console, I've found example of how to cancel tasks and how to cancel parallel loops, but I am unsure as how to do it for nested processes.
Below is the code I have at the moment
From my console app:
using (IUnityContainer container = Bootstrapper.Initialise())
{
IImageProcessor processor = container.Resolve<IImageProcessor>();
processor.Container = container;
try
{
InputArguments arguments = new InputArguments(args);
if (arguments.Contains("fs"))
{
processor.Initialise(arguments["fs"]);
}
else
{
processor.Initialise();
}
processor.Run();
Console.WriteLine("\r\n\n\nPress any key to Exit");
Console.ReadLine();
return (int)ExitCode.Success;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine("\r\n\n\nPress any key to Exit");
Console.ReadLine();
return (int)ExitCode.UnknownError;
}
}
The Run method
public void Run()
{
List<Task> tasks = new List<Task>();
foreach (IFileService fileservice in this.fileServices)
{
Task task = Task.Factory.StartNew((arg) =>
{
IFileService fs = (IFileService)arg;
string msg = $"Processing {fs.ToString()}...";
FileLogger.Write(msg, fs.ToString());
ConsoleLogger.WriteLine(msg);
fs.ProcessFiles();
//fileservice.ReprocessUnMatchedData();
}, fileservice);
tasks.Add(task);
}
Task.WaitAll(tasks.ToArray());
}
and inside each file service I have call this method:
protected bool ProcessFileRecord<T>() where T : IDataRecord
{
int matched = 0;
int notMatched = 0;
int skipped = 0;
bool result;
object lockObject = new object();
try
{
processTracker = GetTracker();
if (databaseHelper.TrackerFullyProcessed(processTracker))
{
LoggingService.Write("File already processed... Skipping.", LoggingTarget.All, serviceName);
result = true;
}
LoggingService.Write($"\r\nProcessing index file {fileRecord.IndexFileName}", LoggingTarget.File, serviceName);
Parallel.ForEach(
fileRecord.DataRecords,
new ParallelOptions() { MaxDegreeOfParallelism = Thread.CurrentThread.ManagedThreadId },
(item) =>
{
switch ((RecordProcessResult)ProcessRecord(item))
{
case RecordProcessResult.Invalid:
break;
case RecordProcessResult.Matched:
Increment(ref matched);
break;
case RecordProcessResult.NotMatched:
Increment(ref notMatched);
break;
case RecordProcessResult.Skipped:
Increment(ref skipped);
break;
default:
break;
}
lock (lockObject)
{
if ((matched + notMatched + skipped) % 100 == 0)
{
LoggingService.Write($"\tMatched: {matched}\tNot Matched: {notMatched}\tSkipped: {skipped}\t total: {matched + notMatched + skipped}", LoggingTarget.Trace & LoggingTarget.Console, serviceName);
}
}
});
LoggingService.Write($"Total Lines: {matched + notMatched + skipped} \r\nMatched: {matched} \r\nNot Matched: {notMatched} \r\nSkipped: {skipped}", LoggingTarget.All, serviceName);
this.databaseHelper.UpdateTracker(this.processTracker, matched, notMatched);
result = true;
}
catch (Exception ex)
{
LoggingService.Write($"Error processing data file:{fileRecord.IndexFileName}", LoggingTarget.All, serviceName);
LoggingService.Write($"{ex.ExceptionTreeAsString()}", LoggingTarget.All, serviceName);
LoggingService.Write($"Total Lines: {(matched + notMatched + skipped)} \r\nMatched: {matched} \r\nNot Matched: {notMatched} \r\nSkipped: {skipped}", LoggingTarget.All, serviceName);
this.databaseHelper.UpdateTracker(this.processTracker, matched, notMatched);
result = false;
}
return result;
}
Thank.
Please, look an example on this page
CancellationTokenSource
Yesterday I've found out how to create several async http requests without async/await. But today I need to do it in a loop: if some of responses don't satisfy some condition - I need to change a request for them and send these requests again. It may be repeated several times.
I've tried this code:
do
{
var loadingCoordinatesTasks = new List<Task<Terminal>>();
var totalCountOfTerminals = terminalPresetNode.ChildNodes.Count;
var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
foreach (var terminal in terminals.Except(_terminalsWithCoordinates))
{
var address = terminal.GetNextAddress();
var webRequest = (HttpWebRequest)WebRequest.Create(GeoCoder.GeoCodeUrl + address);
var webRequestTask = Task.Factory.FromAsync<WebResponse>(webRequest.BeginGetResponse,
webRequest.EndGetResponse,
terminal);
var parsingTask = webRequestTask.ContinueWith(antecedent =>
{
// Parse the response
});
loadingCoordinatesTasks.Add(parsingTask);
}
Task.Factory.ContinueWhenAll(loadingCoordinatesTasks.ToArray(), antecedents =>
{
foreach (var antecedent in antecedents)
{
var terminalWithCoordinates = antecedent.Result;
if (antecedent.Status == TaskStatus.RanToCompletion &&
!terminalWithCoordinates.Coordinates.AreUnknown)
{
_terminalsWithCoordinates.Add(terminalWithCoordinates);
_countOfProcessedTerminals++;
}
}
});
} while (_countOfProcessedTerminals < totalCountOfTerminals);
but is it possible to check the condition in while just after every single set of requests executed?
You can perform the check after increasing the count:
_countOfProcessedTerminals++;
if (_countOfProcessedTerminals >= totalCountOfTerminals)
{
break;
}
Is _countOfProcessedTerminals thread-safe though?
I manage to do it using recursion:
public void RunAgainFailedTasks(IEnumerable<Task<Terminal>> tasks)
{
Task.Factory.ContinueWhenAll(tasks.ToArray(), antecedents =>
{
var failedTasks = new List<Task<Terminal>>();
foreach (var antecedent in antecedents)
{
var terminal = antecedent.Result;
// Previous request was failed
if (terminal.Coordinates.AreUnknown)
{
string address;
try
{
address = terminal.GetNextAddress();
}
catch (FormatException) // No versions more
{
continue;
}
var getCoordinatesTask = CreateGetCoordinatesTask(terminal, address);
failedTasks.Add(getCoordinatesTask);
}
else
{
_terminalsWithCoordinates.Add(terminal);
}
}
if (failedTasks.Any())
{
RunAgainFailedTasks(failedTasks);
}
else
{
// Display a map
}
}, CancellationToken.None,
TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
}
private Task<Terminal> CreateGetCoordinatesTask(Terminal terminal, string address)
{
var webRequest = (HttpWebRequest)WebRequest.Create(GeoCoder.GeoCodeUrl + address);
webRequest.KeepAlive = false;
webRequest.ProtocolVersion = HttpVersion.Version10;
var webRequestTask = Task.Factory.FromAsync<WebResponse>(webRequest.BeginGetResponse,
webRequest.EndGetResponse,
terminal);
var parsingTask = webRequestTask.ContinueWith(webReqTask =>
{
// Parse the response
});
return parsingTask;
}