Using a nested class to pass multiple arguments into a backgroundworker - c#

I'm trying to use a nested class to get two classes to pass into a single argument so I can send it to a backgroundworker. Thus far, I've managed to pass single arguments into a backgroundworker but I'm yet to do it with a nested class where I end up passing both or my desired classes into the same argument. So far here is some of the code I'm using:
This is the Nested Class I'm attempting to use:
public class MyBackGroundWorkerObject
{
public class TimeZone
{
public string Zone;
public int difference;
public override string ToString()
{
return Zone;
}
}
public class AccountName
{
public string AccountSid;
public string AuthToken;
public string Name;
public override string ToString()
{
return Name;
}
}
}
Here's an example of one of the classes in action:
MyBackGroundWorkerObject.AccountName acct = new MyBackGroundWorkerObject.AccountName();
//AccountName acct = new AccountName();
acct.AccountSid = "abcd";
acct.AuthToken = "xyz";
acct.Name = "Potato";
ddlAccounts.Items.Add(acct);
MyBackGroundWorkerObject.TimeZone region = new MyBackGroundWorkerObject.TimeZone();
//TimeZone region = new TimeZone();
region.Zone = "UTC";
region.difference = 0;
comboBox1.Items.Add(region);
And here's the part where I'm utterly confused, I'd like to be able to use both of these when calling from the Window's Form from where it's retrieving some of the entered data. I'm not sure on how to get both of these classes to work in conjuction where I can send them both at the same time to the backgroundworker:
MyBackGroundWorkerObject myBackGroundWorker1 = new MyBackGroundWorkerObject();
object obj = ddlAccounts.SelectedItem;
MyBackGroundWorkerObject.AccountName acct = obj as MyBackGroundWorkerObject.AccountName;
backgroundWorker1.RunWorkerAsync(acct);

You defined the nested classes inside MyBackGroundWorkerObject but there is no variable of type TimeZone nor of type AccountName declared inside the MyBackGroundWorkerObject class.
public class MyBackGroundWorkerObject
{
public class TimeZone
{
public string Zone;
public int difference;
public override string ToString()
{
return Zone;
}
}
public class AccountName
{
public string AccountSid;
public string AuthToken;
public string Name;
public override string ToString()
{
return Name;
}
}
public TimeZone TheTimeZone {get; set;}
public AccountName TheAccountName {get; set;}
}
Now you can set your instances via the TheTimeZone and the TheAccountName members respectively and access them when you pass the MyBackGroundWorkerObject.
MyBackGroundWorkerObject myBackGroundWorker1 = new MyBackGroundWorkerObject();
MyBackGroundWorkerObject.AccountName acct = new MyBackGroundWorkerObject.AccountName();
//AccountName acct = new AccountName();
acct.AccountSid = "abcd";
acct.AuthToken = "xyz";
acct.Name = "Potato";
ddlAccounts.Items.Add(acct);
MyBackGroundWorkerObject.TimeZone region = new MyBackGroundWorkerObject.TimeZone();
//TimeZone region = new TimeZone();
region.Zone = "UTC";
region.difference = 0;
comboBox1.Items.Add(region);
myBackGroundWorker1.TheTimeZone = region;
myBackGroundWorker1.TheAccountName = acct;
backgroundWorker1.RunWorkerAsync(myBackGroundWorker1);
Inside the background worker doWork cast it to MyBackGroundWorkerObject and access it via .TheTimeZone and .TheAccountName again

Related

how to declare a class using the new keyword as property in a static class in c#

I am currently building a namespace to handle complicated string actions. because I use the this string keyword, I must declare where the functions and properties are located as static. (the name of this class is "StringExtension") now I have another class named StringExtensionSettings and I use its boolean properties to determent what functions in the class StringExtension will be enabled. (for the user to choose what functions he wants to use and what not)
ex:
public class StringExtensionSettings
{
public bool DecryptString { get; set; } = true;
public bool EncryptString { get; set; } = true;
public bool RandomMix { get; set; } = true;
public bool AddMidSubString { get; set; } = true;
}
I don't want to warp the string in a class because it will make it complicated for the user. is there is any way to enable or disable function in a static class based on another class properties? and/or how to declare a class within a static class?
thank you in advance!
Additional resources:
the StringExtension class:
static class StringExtension
{
//this is what I'm trying to declare: gives an error
public StringExtensionSettings StringSettings = new StringExtensionSettings();
public static string AddMidSubString(this string Str, string MidSubString)
{
StringBuilder Result = new StringBuilder(Str);
Result.Insert(Result.Length / 2, MidSubString);
return Result.ToString();
}
public static string RandomMix(this string Str)
{
char[] array = Str.ToCharArray();
Random rng = new Random();
int n = array.Length;
while (n > 1)
{
n--;
int k = rng.Next(n + 1);
var value = array[k];
array[k] = array[n];
array[n] = value;
}
return new string(array);
}
// and more functions...
Follow-up of my comment in the OP
Within a Singleton (class), you are still able/ allowed to define fields.
The singleton design pattern is an interface. It is a popular class
type for programs. It allows a class to enforce that it is only
allocated (read -> created) once.
public sealed class StringExtensionSettings
{
private StringExtensionSettings()
{
}
private static StringExtensionSettings instance = null;
public static StringExtensionSettings Instance
{
get
{
if (instance == null)
{
instance = new StringExtensionSettings();
}
return instance;
}
}
public bool DecryptString { get; set; } = true;
public bool EncryptString { get; set; } = true;
public bool RandomMix { get; set; } = true;
public bool AddMidSubString { get; set; } = true;
}
Usage:
Single Field call
StringExtensionSettings.Instance.AddMidSubString
Implementation
public static string AddMidSubString(this string Str, string MidSubString)
{
if (StringExtensionSettings.Instance.AddMidSubString)
{
StringBuilder Result = new StringBuilder(Str);
Result.Insert(Result.Length / 2, MidSubString);
return Result.ToString();
}
throw new Exception($"Not allowed to call {nameof(AddMidSubString)}");
}
Summarized; calling StringExtensionSettings.Instancecreates a new instance of StringExtensionSettings, only (once!), when the private field instance of StringExtensionSettings is null.

Way to set property depending on other property

So, I have this code
Process[] processesManager = Process.GetProcesses();
List<ProcessInfo> temporaryProcessesList = new List<ProcessInfo>();
for (int i = 0; i < processesManager.Length; ++i)
{
temporaryProcessesList.Add(new ProcessInfo(processesManager[i].ProcessName, processesManager[i].Id, TimeSpan.Zero, "Group"));
}
processesList = temporaryProcessesList.GroupBy(d => new {d.Name}).Select(d => d.First()).ToList();
This code is used for getting current processes. Then I'm adding those procesess to temporaryProcessesList. And instead of simple string "Group" I want to set the property depending of the name of process. For example if process has name leagueoflegends.exe then I would like to set the group to "Games", if its devenv.exe I would like to set the group to "Software development".
And my question is, how to do it the simplest/best way? I was thinking about using Dictionary with string and enum. And comparing the ProcessName with string. But maybe there is better way to do it.
ProcessInfo is simple class with 4 properties and constructor.
public class ProcessInfo
{
private string Name { get; set; }
private int Id { get; set; }
private TimeSpan Time { get; set; }
private string Group { get; set; }
public ProcessInfo(string name, int id, TimeSpan time, string group)
{
Name = name;
Id = id;
Time = time;
Group = group;
}
}
Using dictionary is the best way to accomplish this:
var dictionary = new Dictionary<string, string>();
dictionary.Add("a.exe", "aGroup");
dictionary.Add("b.exe", "bGroup");
string val;
if (dictionary.TryGetValue(processName, out val))
processInfo.Group = val;
else
processInfo.Group = "Undefined Group";
Maybe this is what you are looking for:
public class ProcessInfo
{
private string _name;
private string Name
{
get { return _name; }
set
{
_name = value;
UpdateGroupName();
}
}
private int Id { get; set; }
private TimeSpan Time { get; set; }
private string Group { get; set; }
private void UpdateGroupName()
{
Group = ProcessNames::GetGroupFromProcessName(Name);
}
public ProcessInfo(string name, int id, TimeSpan time)
{
Name = name;
Id = id;
Time = time;
}
}
internal static class ProcessNames
{
private static Dictionary<string, string> _names;
public static string GetGroupNameFromProcessName(string name)
{
// Make sure to add locking if there is a possibility of using
// this from multiple threads.
if(_names == null)
{
// Load dictionary from JSON file
}
// Return the value from the Dictionary here, if it exists.
}
}
This design isn't perfect, but hopefully you see the idea. You could also move the update of the Group name to the constructor, but then it would not change the Group name if you set the property after construction.
Also, you could clean the interface up by using INotifyPropertyChanged and/or dependency injection. https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

Object within an object is null

I'm using C# and have created an object to send to a JSON service that looks like this:
public class SendRequest
{
public string id { get; set; }
public string case { get; set; }
public string method { get; set; }
public Volume value { get; set; }
}
public class Volume
{
public int level;
public bool mute;
}
I can code hint when setting the sub object:
var _req = new SendRequest();
_req.value.mute = false;
_req.value.level = 50;
But when the program is run, the sub-object itself is null (_req.value = null) and the two items under that object don't show.
Why is this happening?
You need to initialize the "value" to something.
Add this constructor to your SendRequest class:
public SendRequest(){ value = new Volume(); }
You can use object initializers
var _req = new SendRequest()
{
value = new Volume()
{
mute = false,
level = 50,
},
};
at this point method is null
public string method { get; set; }
longer but what you can do is
private string method = string.empty;
public string Method { get {return method;} set {method = value;} }
value is just a bad name
private Volume volume = new Volume();
public Volume Volume { get {return volume;} set {volume = value;} }
or
volume = new Volume (mute = false, value.level = 50);

Returned json array contains objects with all properties missing

Iam implemented a webservice using c# webapi,but my json response array is empty.
My code
public object Post([FromBody] castdet castdet1)
{
mid = castdet1.mid1;
return Request.CreateResponse(jsonvalues(mid));
}
private object jsonvalues(string mid)
{
DataTable dtalcast = GetAllcast();
foreach (DataRow drow in dtalcast.Rows)
{
string mouvieid = drow["MovieMasterId"].ToString();
string actname = drow["ActorName"].ToString();
string charname = drow["CharacterName"].ToString();
if (mouvieid == mid)
{
temp = 1;
castdet.Add(new myobject(actname, charname));
}
}
return castdet;
}
public class castdet
{
public string mid1 { get; set; }
}
public class myobject
{
string actorname;
string charactername;
public myobject(string v1, string v2)
{
actorname = v1;
charactername = v2;
}
}
My json response string is like this [{},{}],its empty.What went wrong for me?
You need to make the fields of myobject be public. Or better yet make them be public properties:
public class myobject
{
public string actorname { get; set; }
public string charactername { get; set; }
public myobject(string actorname, string charactername)
{
this.actorname = actorname;
this.charactername = charactername;
}
}
(You may have other problems - your code is incomplete and does not compile. Also, you should modify your methods to explicitly return the actual types being returned, not just to return object. This allows for compile-time checking for type errors.)

Changing a class's property from another class

I have a class with properties:
public class TaskConfiguration
{
public string Task_Name
{
get; set;
}
public string task_id
{
get; set;
}
}
And somewhere in the code I have a method to set the properties of the class early on upon program execution:
public class TaskManagingProcess
{
public void InsertTaskProperties()
{
TaskConfiguration tc = new TaskConfiguration();
tc.Task_Name = "Sample Task";
tc.task_id = "1";
}
}
Later in execution, in another class, I want to modify the properties of the TaskConfiguration class, but I'm not sure how. If I use the following, it will not work because it creates a new instance of the TaskConfiguration class.
TaskManagingProcess tmp = new TaskManagingProcess;
tmp.InsertTaskProperties();
So how can I do this?
You want to pass the object:
public void InsertTaskProperties(TaskConfiguration config) {
config.Task_Name = "Sample Task";
config.task_id = "1";
}
Then:
TaskManagingProcess tmp = new TaskManagingProcess();
TaskConfiguration config = new TaskConfiguration();
tmp.InsertTaskProperties(config);
(I am making an awfully large assumption about your code.. but this should give you the basic idea)
It looks to me like TaskManagingProcess is a proxy class that's why I would recommend something like:
public class TaskConfiguration
{
public string Task_Name
{
get;
set;
}
public string task_id
{
get;
set;
}
}
public class TaskManagingProcess
{
private TaskConfiguration taskConfiguration;
public TaskManagingProcess(TaskConfiguration taskConfiguration)
{
this.taskConfiguration = taskConfiguration;
}
public void InsertTaskProperties(string taskId, string name)
{
taskConfiguration.task_id = taskId;
taskConfiguration.Task_Name = name;
}
}
So at the end you could do this (see below) and easily add code to handle the access at your TaskConfiguration object:
TaskConfiguration taskConfiguration = new TaskConfiguration() { task_id = "1", Task_Name = "Sample Task" };
TaskManagingProcess taskManaginProcess = new TaskManagingProcess(taskConfiguration);
taskManaginProcess.InsertTaskProperties("2", "Sample Task 2");

Categories

Resources