|
I don't discount your psychic powers
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
It is very rude to post your home work and not even have the decency to ask a question. We'll gladly help but you have to actually ask something. We don't mind read (most of us at least) and we won't do everything for you.
The fact that you did not even post an appropriate title makes me think you don't know what to ask because you don't know what you are doing.
Social Media - A platform that makes it easier for the crazies to find each other.
Everyone is born right handed. Only the strongest overcome it.
Fight for left-handed rights and hand equality.
|
|
|
|
|
If you are using OLEDB to read the data you can check the ValueType property on a cell.
|
|
|
|
|
Read a chunk (Excel Range) into a C# DataTable, and look at the Column Types: then you know the Type of any Cell in that Column.
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
I do not understand why there is an UnobservedTaskException in that code at all...
A method in a WCF service is defined as
[OperationContract]
[FaultContract(typeof(RemoteException))]
Task SetInfraredFocus(string _clientName, double _focus);
A WPF application calls out to it via:
public void SetFocus(double _focus)
{
try
{
m_RemoteManualPsControl.SetInfraredFocus(UtilsEnvironment.TerminalName, _focus).Wait();
}
catch (Exception ex)
{
Logger.LogException(Name, ex);
}
}
Note the .Wait() and the catch . That in turn calls the WCF client class
public Task SetInfraredFocus(string _clientName, double _focus)
{
Task task = new Task(() => RemoteChannelProvider.Call(_channel => _channel.SetInfraredFocus(_clientName, _focus)));
task.Start();
return task;
}
True, I ought to add a CallAsync function to our WCF client base class, but that's quite convoluted code there...
The server (a singleton service, multi-threaded) has a simple implementation for the sake of demonstration:
public async Task SetInfraredFocus(string _clientName, double _focus)
{
try
{
await Task.Delay(1);
throw new Exception("Oh f***!");
}
catch (Exception ex)
{
Logger.LogException(Name, ex);
RemoteException.ThrowFaultExceptionFromException(ex);
}
}
And then I get that UnobservedTaskException... Its detail clearly shows where it comes from: it is the RemoteException created from the "Oh f***!" exception of the server. But why does the "catch" in the function on the top not catch the exception?
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
|
|
|
|
|
Bernhard Hiller wrote:
Task task = new Task(() => RemoteChannelProvider.Call(_channel => _channel.SetInfraredFocus(_clientName, _focus))); That line looks suspicious to me.
The RemoteChannelProvider doesn't seem to be a built-in class. What's the signature of the Call method?
What I suspect is happening is this:
SetInfraredFocus returns a Task ;Call may or may not discard that task;- Even if it doesn't discard the task, the
new Task constructor definitely discards it - none of the overloads accept a Func<Task> ; - The task returned from the client therefore doesn't observe the result of the task returned from the server. It could even complete before the server call has finished.
If the RemoteChannelProvider.Call method returns the Task , then you should be able to fix this by replacing the client code with:
public Task SetInfraredFocus(string _clientName, double _focus)
{
return Task.Run(() => RemoteChannelProvider.Call(_channel => _channel.SetInfraredFocus(_clientName, _focus)));
} Task.Run has overloads which accept a Func<Task> . The task returned from these will not complete until the inner task has completed, and it will propagate any exceptions correctly.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That overload does not do the trick either...
The "RemoteChannelProvider" is not a built-in class. The signature is:
public delegate void CallProxyDelegate<in T>(T _channel);
...
void Call(CallProxyDelegate<T> _codeBlock, [CallerMemberName] string _functionName = ""); Some implementation details:
m_ConfigurationChannelFactory = new ConfigurationDuplexChannelFactory<T>(m_CallbackObject, ConfigurationName, null, config);
...
m_CommunicationChannel = (ICommunicationObject)m_ConfigurationChannelFactory.CreateChannel();
...
_codeBlock((T)m_CommunicationChannel); I do not know how that handles a Task.
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
|
|
|
|
|
OK, then it's definitely throwing the Task away.
How does the RemoteChannelProvider class cope with server methods which return a value?
If it doesn't, you might still be able to hack around it:
public Task SetInfraredFocus(string _clientName, double _focus)
{
return Task.Run(delegate
{
Task result = null;
RemoteChannelProvider.Call(_channel => result = _channel.SetInfraredFocus(_clientName, _focus));
return result;
});
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Perfect! That hack really works.
(But I still will need some time to find out how it works...)
Oh sanctissimi Wilhelmus, Theodorus, et Fredericus!
|
|
|
|
|
A long time ago, Eric wrote: Quote: Any time you find yourself switching on a type in a generic you are almost certainly doing something wrong. Generics should be generic; they should operate identically completely independent of the type.
If T can only be int or string then don't write your code this way at all in the first place. Write two methods, one that returns an int and one that returns a string. Of course, Eric is always right !
I thought the new pattern-matching facilities in C# 7,8 might allow me to simplify a 'Switch based on a Generic Type; here's a compilable (VS 2019, FrameWork 4.8) example:
public TKey GetNextKey(TKey key = default(TKey))
{
if (! KeysUsed.Contains(key))
{
CurrentKey = key;
KeysUsed.Add(key);
return key;
}
switch (KeyType)
{
case Type _ when KeyType == typeof(Int32):
int i = (Int32) (object) key + 1;
CurrentKey = (TKey)(object) i;
break;
case Type _ when KeyType == typeof(string):
string s = (string) (object) key;
s += GetAGuid();
CurrentKey = (TKey)(object)s;
break;
default:
throw new ArgumentException("unsupported TKey Type");
}
KeysUsed.Add(CurrentKey);
return CurrentKey;
} Okay, if you think "case Type _ when KeyType == typeof(Int32):" is simplification ... game over.
What really irritates me is the conversions to object necessary here. This issue came up in a QA question here in 2016; see FES_SiteCore's solution: [^]
references: Mads Torgensen on C# 8 patterns: [^], ReSharper recent blog: [^]
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
modified 18-Jul-19 10:32am.
|
|
|
|
|
BillWoodruff wrote:
TKey key = default(TKey) Since you're using a recent compiler version, you can omit the type name from the default keyword here:
public TKey GetNextKey(TKey key = default)
BillWoodruff wrote:
if (! KeysUsed.Contains(key))
{
CurrentKey = key;
KeysUsed.Add(key);
return key;
} If KeysUsed is a HashSet<TKey> , you can simplify that to:
if (KeysUsed.Add(key))
{
CurrentKey = key;
return key;
}
BillWoodruff wrote:
switch (KeyType) As you've shown, this is a horrible way to solve the problem. I'd be inclined to make the "next key generation" strategy external to the class, and pass it in via the constructor:
public class Foo<TKey>
{
private readonly HashSet<TKey> KeysUsed;
private readonly Func<TKey, TKey> GenerateNextKey;
public Foo(Func<TKey, TKey> generateNextKey, IEqualityComparer<TKey> comparer = default)
{
if (generateNextKey is null) throw new ArgumentNullException(nameof(generateNextKey));
GenerateNextKey = generateNextKey;
KeysUsed = new HashSet<TKey>(comparer ?? EqualityComparer<TKey>.Default);
}
public TKey CurrentKey { get; private set; }
public TKey GetNextKey(TKey key = default)
{
while (!KeysUsed.Add(key))
{
key = GenerateNextKey(key);
}
CurrentKey = key;
return key;
}
} You could then provide static key generators and/or factory methods to simplify creating the class:
public static class Foo
{
public static class Int32
{
public static readonly Func<int, int> GenerateNextKey = i => i + 1;
public static Foo<int> Create() => new Foo<int>(GenerateNextKey);
}
public static class String
{
public static readonly Func<string, string> GenerateNextKey = s => s + GetAGuid();
private static string GetAGuid() => Guid.NewGuid().ToString("N");
public static Foo<string> Create(IEqualityComparer<string> comparer = default) => new Foo<string>(GenerateNextKey, comparer);
}
} Usage:
Foo<int> fooInt = Foo.Int.Create();
Foo<string> fooString = Foo.String.Create(StringComparer.OrdinalIgnoreCase);
Foo<Guid> fooGuid = new Foo<Guid>(_ => Guid.NewGuid());
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks for this detailed response ! My conclusion is that making a "next key" generator ... where the constraint is to ensure keys are unique ... is best off-loaded to a user-supplied Func passed in to the Class instance as a parameter. I can still do validation in the generic class.
I find it wonderful you describe the code as 'horrible' ... and I agree ! ... since your posting the example of casting voodoo here, as a comment: [^] in 2016 was a source
As I study your code and comments, I look forward to more insights.
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
I think what C#/.NET would need (and I'm not sure it's even possible) in order to completely obviate the need for type checking in generics is a way to do true specialization at the very least.
Unless I'm missing something (and I don't have an example offhand but I run into it from time to time), you can't entirely replace the ability to declare both MyClass<t> and MyClass<char> with function template specialization, short of using all static classes or something.
I always felt like either I was missing something, or .NET was here.
Generics always struck me as less elegant than C++ source based templates anyway. I like the idea of them being truly typed and binary but the tradeoffs are irritating.
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
I think all-in-all C# Generics are excellent, and I think the case I've described here is an "edge case."
I don't have your experience with C++ templates to compare it to.
Given my intense respect for Eric Lippert, over many years, I heed his voice.
«Where is the Life we have lost in living? Where is the wisdom we have lost in knowledge? Where is the knowledge we have lost in information?» T. S. Elliot
|
|
|
|
|
Lippert is solid. I've read him off and on over the years. I'm not disagreeing with him as such. More like a "gosh it would be nice" scenario.
C++'s template system is really elegant. You can actually get the compiler to do do complex computations (like generating parse tables - see the Spirit framework) all at compile time, using a combination of macros and templates. That's an extreme example, but illustrates the flexibility.
Generics don't have the advantage of source level control - they aren't "fancy typed checked source macros" like C++ templates are. They are binary. That's advantageous for a number of reasons, just not in this case.
And you're right it's probably kind of an edge case. But it's one I ran headfirst into in a non-trivial coding project (my regular expression engine)
I could have made the FA engine far more flexible if I had had template specialization. In order to keep the functionality I had, I had to limit it to only dealing with char inputs. =/
When I was growin' up, I was the smartest kid I knew. Maybe that was just because I didn't know that many kids. All I know is now I feel the opposite.
|
|
|
|
|
I am struggling to deserialize a load of JSON as below (the relevant sections).
The problem is the last array titled volunteer_properties which the DataContractJsonSerializer seems to have a problem with. It appears to me to be an array of anonymous objects, each of which contains a named object which has a number of members. So my DataContract entries are trying to follow the same pattern. The array named "roles" is deserialized quite correctly. Note the deserializer recognises the array and creates it, but each object is null.
I have tried a number of different approaches, including naming the Propentry member corresponding to "first_name", etc, changing the type of the array, etc., all to no avail.
If anyone has a suggestion as to how to get past this I will be most grateful.
[DataContract]
internal class Role
{
[DataMember]
internal int id;
[DataMember]
internal string name;
[DataMember]
internal string suffix;
}
[DataContract]
internal class Property
{
[DataMember]
internal int id;
[DataMember]
internal string org_name;
[DataMember]
internal string value;
}
[DataContract]
internal class Propentry
{
[DataMember]
internal Property property;
}
[DataContract]
internal class Properties
{
[DataMember]
internal Propentry propentry;
}
[DataContract]
internal class Volunteer
{
[DataMember]
internal int id;
[DataMember]
internal Role[] roles;
[DataMember]
internal Propentry[] volunteer_properties;
}
[DataContract]
internal class VolList
{
[DataMember]
internal Volunteer[] volunteers;
}
modified 18-Jul-19 12:19pm.
|
|
|
|
|
Have you tried feeding your JSON into a class generator and comparing them?
I use json2csharp - generate c# classes from json[^] which does it pretty well most times.
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thanks I will give it a try.
|
|
|
|
|
The generator worked fine, but the deserializer still fails. I am drawn to the conclusion that it is the structure of the data. I will talk to the people who produce it.
|
|
|
|
|
The DataContractJsonSerializer is not particularly flexible, but you can make this work. (Assuming you're using .NET 4.5 or later.)
.net - Any way to make DataContractJsonSerializer serialize Dictionaries properly? - Stack Overflow[^]
Based on your sample JSON, the classes I came up with are:
public class PropertyValue
{
public int id { get; set; }
public string org_name { get; set; }
public string value { get; set; }
}
public class Role
{
public int id { get; set; }
public string name { get; set; }
public string suffix { get; set; }
}
public class Volunteer
{
public int id { get; set; }
public IList<Role> roles { get; set; }
public IList<IDictionary<string, PropertyValue>> volunteer_properties { get; set; }
}
public class Root
{
public Volunteer volunteer { get; set; }
} With those classes in place:
var ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
var ser = new DataContractJsonSerializer(typeof(Root), new DataContractJsonSerializerSettings(){ UseSimpleDictionaryFormat = true });
var root = (Root)ser.ReadObject(ms);
The volunteer_properties property is a pain - it's a list of dictionaries, each containing a single entry using the property name as a key. If you switched to JSON.NET, you could use a custom converter to tidy that up. But if you can change the source JSON, you could simplify it to:
"volunteer_properties": {
"first_name":{
"id":3990,
"org_name":"First Name",
"value":"Richard"
},
"surname":{
"id":3991,
"org_name":"Surname",
"value":"MacCutchan "
},
} which would then let you remove the IList<...> from the property declaration:
public IDictionary<string, PropertyValue> volunteer_properties { get; set; } giving you a single dictionary of properties.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks for the excellent response Richard, that was indeed the answer.
|
|
|
|
|
I am having windows application in asp.net using vb.net as a language. I have scheduled that application using task Scheduler and it will schedule that .exe every after 5 minutes. So whenever this .exe executes it is throw an Error i.e; "Window Class Name is Not valid" or "Error Creating Window Handle()". So anyone can help me on that. I am stuck on that from last 2 days.
Thanks,
|
|
|
|
|
Does your program include the line Application.EnableVisualStyles(); ?
does your app use TreeView controls ?
If so, try again with that line removed. Things may look slightly different, but the program might work, according to parts of this[^] and this [^] .
Googling for "window class name is not valid" yielded that (and many other pages) in a matter of minutes, not sure it will solve your situation, but it basically seems to be a Microsoft problem.
|
|
|
|
|
No, my application does not have Application.EnableVisualStyles() and Treeview Control.
It contains ListView and Panels with Labels and Textboxes.
|
|
|
|
|
That is too bad
You may want to ask Google and read all you get. One frequent idea there is insufficient access to a code folder.
BTW: you are in the wrong forum, this should be about C#, not VB.NET; but then, you're not the first VBer today to visit and ask here
|
|
|
|