|
"Sortable". Before, during, or after? One time or repeatedly? You can built multiple dictionaries over the same set all having a different order ... the "keys collection" is then in order (with which to retrieve the "values"). Or, sort the values before loading them with an "entity id.".
All the concurrent collections require some sort of "destaging" if you want a "list"
I didn't think you actually meant you wanted to be able to (live) sort a "concurrent" (list) file.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
modified 22-May-23 18:07pm.
|
|
|
|
|
? [^] ... a Collection with unspecified order.
«The mind is not a vessel to be filled but a fire to be kindled» Plutarch
|
|
|
|
|
You woke up just for that?
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Well, there's this internal class from the .NET Framework source:
ThreadSafeList - Reference Source[^]
But the obvious question is, what's the expected use-case? The Concurrent collections are typically designed to be as lock-free as possible. Appending an item to a list from multiple threads doesn't lend itself to that approach. And if two threads append an item at the same time, what order do you expect them to appear in?
Perhaps you're looking for something more like a producer-consumer pattern[^]? Or perhaps a ConcurrentQueue[^]?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Richard Deeming wrote: And if two threads append an item at the same time, what order do you expect them to appear in? That's why the collection should support sorting.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
As Gerry said, sorting at what point?
If the list must always be sorted, then there's no option but to lock the entire list on every modification.
If you only want the list sorted after you've finished populating it, then it's better to use an unsorted concurrent collection (eg: ConcurrentBag<T> ), and then sort the items when you consume them.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Just noting that usually when I design something where threads are a problem, and once I consider it, I very seldom want a collection itself that is thread safe.
I end up writing a container that controls access to the collection.
I can't be sure about all that I consider but I do know that there are optimizations for access which can only be controlled via container. Adding those if one is using the collection directly can be a problem.
Sometimes I even make the container into a collection. Where the real collection is a attribute (not parent). Yes that is more work but it still insures control.
|
|
|
|
|
You could use ImmutableList as an alternative to locking.
1) Copy the reference to the list into a temporary variable used (not a field)
2) Call add/delete/whatever on your reference copy from step 1. Notice this will NOT update the original list but return a reference to a new list. Keep this result separate, do not override the reference you got in step 1.
3) Use Interlocked.CompareExchange to assign this new reference back to the place you got it from in step 1
If Interlocked.CompareExchange does not return the value you got in 1), then it means someone else altered the list at the same time you where doing it. You can take the returned value and run step 2) and 3) again (yes, all of this can be written as a somewhat readable loop).
This will avoid locks, but at the risk of running the list modification multiple times in case of conflict. If performance is important you would need to measure if this is faster than a simple lock. If both are fast enough, use whatever you find most readable.
If you are updating the list concurrently order is of course not guarantied - but it is guarantied multiple operations performed in step 2) above would be performed as an atomic operation - you will never access the list where it only contains some of the pending modifications.
|
|
|
|
|
I think that is a brilliant idea! I will consider it.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Is it possible to open a browser with Process.Start("www.someplace.com") and wait for a callback?
If so, what would that look like? I need to call Google People API in the default browser and wait for the redirect URL.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
Callback? What callback?
No. You're "fire and forget" launching a new process that runs independently from your code. There is no callback or notification of anything completing in the browser.
You can call the Google API using an HttpClient and you'll have much greater control over the request and response process.
|
|
|
|
|
Ya, I was just hoping.
Thanks anyhow
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|
|
This?
Window: DOMContentLoaded event - Web APIs | MDN
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
That fires inside the browser. It's not raised, or even exposed, to a separate process that launched the browser.
|
|
|
|
|
|
You'd have to use the WebView2 control or the WebBrowser in your own app to get at the event.
For one launched though the Process class, not so much.
He never said why he's launching it through Process or anything else related to it so until he does, suggestion after suggestion is a moot point.
|
|
|
|
|
Sorry I didn't clarify...
I need to call Google's People API from a WPF app and wait for authentication. Once authentication is complete, then my app will get contact info. The requirement from Google is that the app not use an embedded browser, so I have to figure out if the user authenticated before continuing.
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 22-May-23 19:54pm.
|
|
|
|
|
OK, so does the Google API have an alternate way to authenticate using credentials the user enters in your app instead of using the Google login page?
|
|
|
|
|
Rather than using a Web browser, you would be better interacting directly with the API.
If you have to use the browser, you could always use a Web driver and Selenium. This should be of interest. How to automate web browser in C# - CODE-AI[^]
|
|
|
|
|
Is it possible to use the same void between multiple forms in the same project?
If it possible, how is it done?
|
|
|
|
|
No idea what that question means.
'void' is a keyword used in C# code.
The most frequent usage is to specify the return type of a method.
A much less frequent usage is as a void pointer in unsafe code usage.
|
|
|
|
|
If you mean a method as in:
void Foo() { ... } And you want to access it from a different form, then there are two things you need to consider:
1) If it is not declared as static then you need an instance of the containing form in order to call it:
MyContainingForm form = new MyContainingForm();
...
form.TheMethodYouWantToCall(); If it is declared as static then you prefix it with the containing form class name:
MyContainingForm.TheMethodYouWantToCall();
2) In both cases, the appropriate access modifiers must be used when declaring both the containing class and the method: Access Modifiers - C# Programming Guide | Microsoft Learn[^]
You may also need to explicitly prefix the namespace name as well.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Let's say that I have this Worker class which uses a Func to process data
public class Worker
{
public Func<int, List<string>> DataSource { get; set; }
public void Execute(int num)
{
var data = DataSource(num);
data.ForEach(x => Console.WriteLine(x));
}
}
I want to call a repository method using the func. Here's the repo method
public class Repo
{
public List<string> GetData(int num)
{
var results = new List<string>();
for (int x = 0; x < num; x++)
{
results.Add($"Result{x}");
}
return results;
}
}
And here's the class that fires it all
internal class Program
{
static void Main(string[] args)
{
var repo = new Repo();
var myClass = new Worker();
myClass.DataSource = repo.GetData;
myClass.Execute(10);
Console.ReadLine();
}
}
Here's the question...
How would I code this so that I wouldn't have to pass in the param to Execute? Can I define the Func with the param as part of it? Maybe something like:
myClass.DataSource = repo.GetData(10);
I don't want to have to pass any parameters into the Worker class. Can the func somehow accept parameters?
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
modified 4-May-23 0:58am.
|
|
|
|
|
Sounds like you're looking for "partial application":
Currying vs partial function application | Jon Skeet's coding blog[^]
For example:
public static class Functional
{
public static Func<TResult> Apply<TArg, TResult>(this Func<TArg, TResult> fn, TArg arg)
{
return () => fn(arg);
}
}
public class Worker
{
public Func<List<string>> DataSource { get; set; }
public void Execute()
{
var data = DataSource();
data.ForEach(x => Console.WriteLine(x));
}
}
internal class Program
{
static void Main(string[] args)
{
var repo = new Repo();
var myClass = new Worker();
myClass.DataSource = Functional.Apply(repo.GetData, 10);
myClass.Execute();
Console.ReadLine();
}
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That's exactly what I need.
Thank you
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
Ya can't fix stupid.
|
|
|
|