✅ System threading tasks

I am trying to accomplish a checker to make sure a task/function doesn't take to long to run. If it does it must end. Basically kill the task. This is the code I have:
c#
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;

System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Run(() => UpdateQueryBox(), cancellationToken);

System.Threading.Tasks.Task delayTask = System.Threading.Tasks.Task.Delay(5000);

System.Threading.Tasks.Task.WaitAny(task, delayTask);

if (!task.IsCompleted)
{
cancellationTokenSource.Cancel();
MessageBox.Show("The server is not responding, please re-try.", "Error");

}
c#
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;

System.Threading.Tasks.Task task = System.Threading.Tasks.Task.Run(() => UpdateQueryBox(), cancellationToken);

System.Threading.Tasks.Task delayTask = System.Threading.Tasks.Task.Delay(5000);

System.Threading.Tasks.Task.WaitAny(task, delayTask);

if (!task.IsCompleted)
{
cancellationTokenSource.Cancel();
MessageBox.Show("The server is not responding, please re-try.", "Error");

}
But with this it is creating cross threading. I had this issue before but with accessing data, and I did this to solve it:
c#
private string GetControlText(Control control)
{
if (control.InvokeRequired)
{
// Call the method recursively in the UI thread
return (string)control.Invoke(new Func<string>(() => control.Text));
}
else
{
return control.Text;
}
}
c#
private string GetControlText(Control control)
{
if (control.InvokeRequired)
{
// Call the method recursively in the UI thread
return (string)control.Invoke(new Func<string>(() => control.Text));
}
else
{
return control.Text;
}
}
This worked, but now the panel (error on picture) that is trying to be accessed is to update it...I update a lot of the information on the form so the same workaround cannot be done. Please lemme know if you need more information.
No description
11 Replies
Bladesfist
Bladesfist3mo ago
Task.Run is most likely the culprit here for moving the task to the other thread, can you make that task return data that the main thread awaits and then uses to update the UI?
Bladesfist
Bladesfist3mo ago
Also if you want, you can install Polly (https://www.nuget.org/packages/polly/) which has timeout as well as a bunch of other resilience strategies built in
Polly 8.3.1
Polly is a .NET resilience and transient-fault-handling library that allows developers to express resilience and transient fault handling policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.
SparkyCracked
SparkyCracked3mo ago
I would be returning an array/object with like 15 items. Would that be ideal? To answer I can make the task return data Will check this out
Bladesfist
Bladesfist3mo ago
Shouldn't be an issue, technically it's returning a reference to the array anyway so it's just the size of a ref, not a copy of the full array
SparkyCracked
SparkyCracked3mo ago
Do you think creating a class entities in this scenario would be good? formsValues for intance And then just have the values for every tool there
Bladesfist
Bladesfist3mo ago
Not sure I know what you mean, to wrap the array response from the task? Probably not
SparkyCracked
SparkyCracked3mo ago
Yeah, or format it basically. Also t prevent my array from putting information in the wrong fields.
c#
[ContentType(Name="Item")]
public partial class Item
{
private Nullable<Int32> _id;
private Nullable<Int32> _version;
private String _title;

[Column]
public Nullable<Int32> Id { get; set; }

[Column]
public Nullable<Int32> Version { get; set; }

[Column]
public String Title { get; set; }

// Other member declarations omitted for readability.
}
c#
[ContentType(Name="Item")]
public partial class Item
{
private Nullable<Int32> _id;
private Nullable<Int32> _version;
private String _title;

[Column]
public Nullable<Int32> Id { get; set; }

[Column]
public Nullable<Int32> Version { get; set; }

[Column]
public String Title { get; set; }

// Other member declarations omitted for readability.
}
So the above is an example of what I speak about. If my function doesn't return the version for instance, it can put "" in that field on the field...and if I want a specific value I can get that. kind of like a dictionary.
Bladesfist
Bladesfist3mo ago
Oh so you'll have an Item[] response? Sounds reasonable
SparkyCracked
SparkyCracked3mo ago
Yes The only concern I have is data races where we now trying to access the same data from different threads I've had the issue before and to this day not sure how to deal with it
Bladesfist
Bladesfist3mo ago
Don't share mutatable state and you're golden
SparkyCracked
SparkyCracked3mo ago
Fair, so an await and return of a new entity based on the class should cover that right? Then just write the returned values into the existing data... That sounded so scuffed, do you understand my thought process here?
c#
using System;
using System.Threading;

class Program
{
static readonly object lockObject = new object();

static void Main(string[] args)
{
Item originalItem = new Item
{
Id = 1,
Version = 1,
Title = "Original Title"
};

Console.WriteLine("Original Item:");
Console.WriteLine($"ID: {originalItem.Id}, Version: {originalItem.Version}, Title: {originalItem.Title}");

Thread thread = new Thread(() =>
{
Item newItem = new Item
{
Id = 2,
Version = 2,
Title = "New Title"
};

Console.WriteLine("\nNew Item (Inside Thread):");
Console.WriteLine($"ID: {newItem.Id}, Version: {newItem.Version}, Title: {newItem.Title}");

lock (lockObject)
{
originalItem = newItem;
}
});

thread.Start();
thread.Join();

lock (lockObject)
{
Console.WriteLine("\nMain Thread:");
Console.WriteLine("The original item is overridden with the item from the thread.");
Console.WriteLine($"ID: {originalItem.Id}, Version: {originalItem.Version}, Title: {originalItem.Title}");
}
}
}
c#
using System;
using System.Threading;

class Program
{
static readonly object lockObject = new object();

static void Main(string[] args)
{
Item originalItem = new Item
{
Id = 1,
Version = 1,
Title = "Original Title"
};

Console.WriteLine("Original Item:");
Console.WriteLine($"ID: {originalItem.Id}, Version: {originalItem.Version}, Title: {originalItem.Title}");

Thread thread = new Thread(() =>
{
Item newItem = new Item
{
Id = 2,
Version = 2,
Title = "New Title"
};

Console.WriteLine("\nNew Item (Inside Thread):");
Console.WriteLine($"ID: {newItem.Id}, Version: {newItem.Version}, Title: {newItem.Title}");

lock (lockObject)
{
originalItem = newItem;
}
});

thread.Start();
thread.Join();

lock (lockObject)
{
Console.WriteLine("\nMain Thread:");
Console.WriteLine("The original item is overridden with the item from the thread.");
Console.WriteLine($"ID: {originalItem.Id}, Version: {originalItem.Version}, Title: {originalItem.Title}");
}
}
}
@🅱ladesfist Imma take this logic into my project, lemme know if you notice anything wrong here or potential issues please I am using the class I sent earlier Seemed to work. Thanks ^^