Are static methods in ASP.NET code-behind classes non-thread-safe? - c#

Can I use static methods in my ASP.NET Pages and UserControls classes if they don't use any instance members? I.e.:
protected void gridView_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gridStatement.DataSource = CreateDataSource();
gridStatement.PageIndex = e.NewPageIndex;
gridStatement.DataBind();
}
private static DataTable CreateDataSource()
{
using (var command = new SqlCommand("SELECT foobar"))
{
var table = new DataTable();
new SqlDataAdapter(command).Fill(table);
return table;
}
}
Or this is not thread-safe?

Yes, you can use static methods - they are thread-safe. Each thread will execute in a separate context and therefore any objects created inside a static method will only belong to that thread.
You only need to worry if a static method is accessing a static field, such as a list. But in your example the code is definitely thread-safe.

nothing shared across threads, so it is thread safe. unless you access static members that other static methods have a chance of executing concurrently with it...

it is. The only thing to worry about in your context about thread-safeness is a concept that involves static members, as already said.
When any method (static or not) accesses a static member, you should worry about multithreading issues.
Consider the following:
public class RaceConditionSample
{
private static int number = 0;
public static int Addition()
{
int x = RaceConditionSample.number;
x = x + 1;
RaceConditionSample.number = x;
return RaceConditionSample.number;
}
public int Set()
{
RaceConditionSample.number = 42;
return RaceConditionSample.number;
}
public int Reset()
{
RaceConditionSample.number = 0;
return RaceConditionSample.number;
}
}
RaceConditionSample sample = new RaceConditionSample();
System.Diagostics.Debug.WriteLine(sample.Set());
// Consider the following two lines are called in different threads in any order, Waht will be the
// output in either order and/or with any "interweaving" of the individual instructions...?
System.Diagostics.Debug.WriteLine(RaceConditionSample.Addition());
System.Diagostics.Debug.WriteLine(sample.Reset());
The answer is: It may be "42, 43, 0", "42, 0, 1" you wont know before..

Related

Why can't my declared non static field be accessed inside static method?

Hi I am new to C# and I am aware on a surface level that I cannot use non static fields inside static methods. But I have a situation that I am trying to understand conceptually.
Check out this code snippet:
class CIMConversionHelper
{
private static Logger Logger = LogManager.GetCurrentClassLogger();
private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
public static TDX2KlarfResult HandleConversion(TDXProcessItem item, string fileName)
{
TDX2KlarfResult result = new TDX2KlarfResult();
result.success = true;
XmlDocument doc = new XmlDocument();
try
{
doc.Load(fileName);
}
catch (Exception ex)
{
result.success = false;
Logger.Error(ex, "XML Parsing Error: ");
return result;
}
_procEndTimeData.ToolType = toolType;
_procEndTimeData.Lot = input.cimToolContext.LOT;
_procEndTimeData.WaferScribe = input.cimWaferContainer.waferContext.WAFER_SCRIBE;
_procEndTimeData.Processing_End_Time = input.cimToolContext.PROCESSING_END_TIME;
}
public static TDX2KlarfResult Convert(TDXProcessItem item, string fileName)
{
TDX2KlarfResult result = new TDX2KlarfResult();
result.success = true;
try
{
result = CIMConversionHelper.HandleConversion(item, fileName);
}
catch (Exception ex)
{
// Failed to Parse the xml Not good mark nonrecoverable error and return.
result.errorType = "Non-Recoverable";
result.success = false;
Logger.Error(ex, "Unknown Error: ");
return result;
}
if (result.success)
{
//DBHelper.AddProcessingEndTimeToDB();
}
return result;
}
}
This is a very abridged snippet but one that captures my question. I have created an object reference as field for ProcessingEndTimeData called _procEndTimeData.
Why then is it telling me in Visual Studio that:
"an object reference is required for the non-static field, method, or property CIMConversionHelper._procEndTimeData?
I thought I should be able to assign values to the declared object "_procEndTimeData" in the 4th line inside the static function "HandleConversion"
Can someone explain to me why this reference is not enough? and why I would then have to create yet another ProcessingEndTimeData object inside the static function HandleCOnversion?
I know I can just toggle _procEndTimeData to be static but why do I need to do this if I have already created a reference in the field level?
Think about the memory of the equipment.
When you create an object, memory is reserved for it. Imagine, that because of its properties (int, char...) it occupies 32 bytes. If you create 10 objects, you will have 320 bytes occupied in memory for your objects.
But when you use "static", those properties are created only once for the class. Not once for each object you create.
So, your 10 objects can access their own properties (int, char...) and also the static ones. But from a "static" method you cannot access the properties of an object of that class because you don't have the instance of it.
A very simple example: You have a User class with the Name property. You add a static variable of type integer: static int count. That variable will be used to record the number of users you create.
In the constructor of the user you can do count++ because the instances of the class can access to the properties of the class. But if you create a static method:
public static void DoSomething()
{
// You can show a message with the number of users
MessageBox.Show(count.ToString());
// But you CAN'T access to a "Name" because this method is not
// a method of one concrete user. It's a general method, for all users
}
If you invoke DoSomething and you are created two users, "Tom" and "Jerry", in DoSomething you don't know any user.
You have 2 choices to make this work. Not sure which one applies. My guess is the first one I will show
private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
change to
static private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
This says that this field is also static, ie belongs to the class, not to instances of the CIMConversionHelper class.
The alternative, which I dont think you want it to create an instance of CIMConversionHelper in that method. Which as I said is probably not what you want.
If your intent is that this class (CIMConversionHelper) is all static, ie you will never create an instance of it then mark the class itself static and the compiler will ensure that you dont accidentally create non static members. ie
static class CIMConversionHelper{....}
Why is this so?
You say you have created a reference here
private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
YOu have not created it yet.
You need to understand the difference between static and instance functions and fields.
Lets have an example. We have a class Thingy. It includes a factory method that makes thingy instances and keeps a count of how many it has made
public class Thingy{
static s_thingyCount = 0;
string _froop;
public static CreateThingy(){
var thing = new Thingy();
......
s_thingyCount++;
thing._froop = "hello";
return thing;
}
public void Twang(int froop){
......
}
public int Oink(string pling){
......
_froop = pling;
}
}
we can go
var t1 = Thingy.CreateThingy();
t1.Oink("Ole");
The CreateThingy does not operate on instances of the class, it operates on the class itself. The count variable does not belong to an instance, it belongs to the class itself. Note that in the create method we have to say
thing._froop = "hello";
ie which objects _froop we want to set (the one we are in the process of making).
var t1 = Thingy.CreateThingy();
now we have an instance of Thingy we can call methods on it
t1.Oink("Ole");
Look in that method
public int Oink(string pling){
......
_froop = pling;
}
we dont say which froop to set, we are manipulating an instance of the class.
We cannot do
Thingy.Oink("xxx");
Which THingy would be updates? Nor can we do
Thingy._froop = "fff";
for the same reason
but we can do
var count = Thingy.s_thingyCount;
How does this map to your class. THis method is static. It is like CreateThingy, it does not have an instance to operate on.
public static TDX2KlarfResult HandleConversion(TDXProcessItem item, string fileName)
but you do this
_procEndTimeData.ToolType = toolType;
with this field
private readonly ProcessingEndTimeData _procEndTimeData = new ProcessingEndTimeData();
this is just like doing
_froop = "hello"
in CreateThingy
_proceEndTimeData only exists in instances on your class.
It will be create when you do
new CIMConversionHelper();
But I suspect thats not what youo want to do. So you need to make _proceEndTimeData static, just like s_thingyCount
If I'm understanding it correctly, you answered yourself: "I am aware on a surface level that I cannot use non static fields inside static methods", and then you have declared a non static variable inside your method:
private readonly ProcessingEndTimeData _procEndTimeData
It should be static, apart than readonly if you want.
The reason for this has to do with object oriented programming. To access a static method from a class you don't need to instantiate it. This is why you can't reference class-level non static variables inside a static method from that class. Hope that made it a little clearer.
I know I can just toggle _procEndTimeData to be static but why do I need to do this if I have already created a reference in the field level?
You created no such thing, your _procEndTimeData is a field in every instance of CIMConversionHelper, of which you have none.
If it helps you visualize the problem better, imagine what would happen if your expectation was reality and you had the following code:
CIMConversionHelper h1 = new(), h2 = new();
CIMConversionHelper.Convert(.....whatever....);
Would it change h1._procEndTimeData? h2._procEndTimeData? It has to pick one, right? So which one does it pick?
No. static methods can only use static fields, period.

Does Instantiating new instance make all code thread safe?

Edited the code to make it thread-safe post comments
Please see the updated question at the end.
Can you please help me understand if this code is thread-safe or how it can be made thread safe?
Setup
My system has a very simple class called WorkItem.
public class WorkItem
{
public int Id {get;set;}
public string Name {get;set;}
public DateTime DateCreated {get;set;}
public IList<object> CalculatedValues {get;set;}
}
There is an interface ICalculator which has a method that takes a work item, performs a calculation and returns true.
public interface ICalculator
{
bool Calculate(WorkItem WorkItem);
}
Let's say we have two implementations of ICalculator.
public class BasicCalculator: ICalculator
{
public bool Calculate(WorkItem WorkItem)
{
//calculate some value on the WorkItem and populate CalculatedValues property
return true;
}
}
Another calculator:
public class AnotherCalculator: ICalculator
{
public bool Calculate(WorkItem WorkItem)
{
//calculate some value on the WorkItem and populate CalculatedValues property
//some complex calculation on work item
if (somevalue==0) return false;
return true;
}
}
There is a calculator handler class. Its responsibility is to execute calculators sequentially.
public class CalculatorHandler
{
public bool ExecuteAllCalculators(WorkItem task, ICalculator[] calculators)
{
bool final = true;
//call all calculators in a loop
foreach(var calculator in calculators)
{
var calculatedValue = calculator.Calculate(WorkItem);
final = final && calculatedValue;
}
return final;
}
}
Finally, in my client class, I inject ICalculators[] which are relevant for the run. I then instantiate ExecuteCalculators() method.
Now I have a large number of work items and I want to perform calculations on them so I create a list of Task, where each task is responsible of instantiating CalculatorHandler instance and then takes a work item and performs calculations by doing a WaitAll() on all of the tasks, e.g.
public class Client
{
private ICalculators[] _myCalculators;
public Client(ICalculators[] calculators)
{
_myCalculators = calculators;
}
public void ExecuteCalculators()
{
var list = new List<Task>();
for(int i =0; i <10;i++)
{
Task task = new Task(() =>
var handler = new CalculatorHandler();
var WorkItem = new WorkItem(){
Id=i,
Name="TestTask",
DateCreated=DateTime.Now
};
var result = handler.ExecuteAllCalculators(WorkItem, _myCalculators);
);
list.Add(task);
}
Task.WaitAll(list);
}
}
This is a simplied version of the system. Actual system has a range of calculators and Calculators and CalculatorHandler are injected via IoC etc.
My questions are - help me understand these points:
Each task creates a new instance of CalculatorHandler. Does this
mean anything that happens in CalculatorHandler is thread safe as it
does not have any public properties and simply loops over
calculators?
Calculators are shared amongst all tasks because they are member variable of Client class but they are passed into
CalculatorHandler which is instantiated for each task. Does it mean that when all tasks run, as new
instance of CalculatorHandler is created therefore Calculators are
automatically thread safe and we will not experience any threading issues e.g. deadlocks etc?
Can you please suggest how I can make the code threadsafe? Is it
best to pass in a Func<'ICalculators>'[] to Client class and then within each task, we can execute Func<'ICalculator'>() and then pass those instances to ICalculator there? Func<'ICalculator'> will return instance of ICalculator.
Is it true that calculators are passed in as private method variable therefore other instances of CalulatorHandler cannot run the same instance of calculator? Or because calculators are reference types, we are bound to get multi thread issues?
Update
Can you please help me understand if this updated code is thread-safe or how it can be made thread safe?
Setup
My system has a very simple class called WorkItem. It has getter public properties except 1 property "CalculatedValues".
public class WorkItem
{
public int Id {get;}
public string Name {get;}
public DateTime DateCreated {get;}
public IList<object> CalculatedValues {get;set;}
public WorkItem(int id, string name, DateTime dateCreated)
{
Id = id,
Name = name,
DateCreated = dateCreated
}
}
There is an interface ICalculator which has a method that takes a work item, performs a calculation and returns a IList. It does not change the state of work item.
public interface ICalculator
{
IList<object> Calculate(WorkItem WorkItem);
}
Let's say we have two implementations of ICalculator.
public class BasicCalculator: ICalculator
{
public IList<object>Calculate(WorkItem WorkItem)
{
//calculate some value and return List<object>
return List<object>{"A", 1};
}
}
Another calculator:
public class AnotherCalculator: ICalculator
{
public bool Calculate(WorkItem WorkItem)
{
//calculate some value and return List<object>
return List<object>{"A", 1, workItem.Name};
}
}
There is a calculator handler class. Its responsibility is to execute calculators sequentially. Note, it takes in ICalculators in its constructor when it is instantiated. It has a private static lock object too when it updates work item instance.
public class CalculatorHandler
{
private ICalculators[] _calculators;
public CalculatorHandler(ICalculators[] calculators)
{
_calculators = calculators;
}
//static lock
private static object _lock = new object();
public bool ExecuteAllCalculators(WorkItem workItem, ICalculator[] calculators)
{
bool final = true;
//call all calculators in a loop
foreach(var calculator in calculators)
{
var calculatedValues = calculator.Calculate(workItem);
//within a lock, work item is updated
lock(_lock)
{
workItem.CalculatedValues = calculatedValues;
}
}
return final;
}
}
Finally, in my client class, I execute CalculatorHandler.
Now I have a large number of work items and I want to perform calculations on them so I create a list of Task, where each task is responsible of instantiating CalculatorHandler instance and then takes a work item and performs calculations by doing a WaitAll() on all of the tasks, e.g.
public class Client
{
public void ExecuteCalculators()
{
var list = new List<Task>();
for(int i =0; i <10;i++)
{
Task task = new Task(() =>
//new handler instance and new calculator instances
var handler = new CalculatorHandler(new[]{
new BasicCalculator(), new AnotherCalculator()
});
var WorkItem = new WorkItem(
i,
"TestTask",
DateTime.Now
};
var result = handler.ExecuteAllCalculators(WorkItem);
);
list.Add(task);
}
Task.WaitAll(list);
}
}
This is a simplied version of the system. Actual system has a range of calculators and Calculators and CalculatorHandler are injected via IoC etc.
My questions are - help me understand these points:
Each task creates a new instance of CalculatorHandler and new instances of ICalculators. Calculators do not perform any I/O operations and only create a new private IList. Is calculator handler and calculator instances now thread safe?
CalculatorHandler updates work item but within a lock. Lock is a static private object. Does it mean all instances of CalculatorHandler will share one single lock and therefore at one point, only one thread can update the work item?
Work item has all public getter properties except its CalculatedValues property. CalculatedValues is only set within a static lock. Is this code now thread-safe?
1) Creating a new instance of a class, even one without public properties does not provide any guarantee of thread safety. The problem is that ExecuteAllCalculators takes two object parameters. The WorkItem object contains mutable properties and the same WorkItem object is used for all ICalculator calls. Suppose one of the calculators decides to call Clear() on WorkItem.CalculatedValues. Or suppose one calculator sets WorkItem.Name to null and the next decides to do a WorkItem.Name.Length. This isn't technically a "threading" issue because those problems can occur without multiple threads involved.
2) Calculator objects shared across threads is definitely not thread safe. Suppose one of the calculator instances uses a class level variable. Unless that variable is somehow thread protected (example: lock {...}), then it would be possible to produce inconsistent results. Depending how "creative" the implementer of the calculator instances were a deadlock could be possible.
3) Any time your code accepts interfaces you are inviting people to "play in your sandbox". It allows code that you have little control of to be executed. One of the best ways to handle this is to use immutable objects. Unfortunately, you can't change the WorkItem definition without breaking your interface contract.
4) Calculators are passed by reference. The code shows that _myCalculators is shared across all tasks created. This doesn't guarantee that you will have problems, it only makes it possible that you might have problems.
No, it is not thread-safe. If there is any shared state in any calculation then the it is possible to have threading issues. The only way to avoid threading issues is to ensure you are not updating any shared state. That means read-only objects and/or using "pure" functions.
You've used the word "shared" - that means not thread-safe by virtue of sharing state. Unless you mean "distributed" rather than "shared".
Exclusively use read-only objects.
They are reference types so they may be shared amongst separate threads - hence not thread-safe - unless they are read-only.
Here's an example of a read-only object:
public sealed class WorkItem : IEquatable<WorkItem>
{
private readonly int _id;
private readonly string _name;
private readonly DateTime _dateCreated;
public int Id { get { return _id; } }
public string Name { get { return _name; } }
public DateTime DateCreated { get { return _dateCreated; } }
public WorkItem(int id, string name, DateTime dateCreated)
{
_id = id;
_name = name;
_dateCreated = dateCreated;
}
public override bool Equals(object obj)
{
if (obj is WorkItem)
return Equals((WorkItem)obj);
return false;
}
public bool Equals(WorkItem obj)
{
if (obj == null) return false;
if (!EqualityComparer<int>.Default.Equals(_id, obj._id)) return false;
if (!EqualityComparer<string>.Default.Equals(_name, obj._name)) return false;
if (!EqualityComparer<DateTime>.Default.Equals(_dateCreated, obj._dateCreated)) return false;
return true;
}
public override int GetHashCode()
{
int hash = 0;
hash ^= EqualityComparer<int>.Default.GetHashCode(_id);
hash ^= EqualityComparer<string>.Default.GetHashCode(_name);
hash ^= EqualityComparer<DateTime>.Default.GetHashCode(_dateCreated);
return hash;
}
public override string ToString()
{
return String.Format("{{ Id = {0}, Name = {1}, DateCreated = {2} }}", _id, _name, _dateCreated);
}
public static bool operator ==(WorkItem left, WorkItem right)
{
if (object.ReferenceEquals(left, null))
{
return object.ReferenceEquals(right, null);
}
return left.Equals(right);
}
public static bool operator !=(WorkItem left, WorkItem right)
{
return !(left == right);
}
}
Once created it can't be modified so thread-safety is no longer an issue.
Now, if I can assume that each ICalculator is also implemented without state, and thus is a pure function, then the calculation is thread-safe. However, there is nothing in your question that let's me know that I can make this assumption. There is no way, because of that, that anyone can tell you that your code is thread-safe.
So, given the read-only WorkItem and the pure ICalculator function, then the rest of your code then looks like it would be perfectly fine.

C# updating a dictionary in a different class

I have a dictionary which holds data and I have threads which handle concurrent client requests. I want some of the client requests to change the values in the dictionary when needed but not sure how to fix scope issues when dealing with threads and classes.
A simplified example of what I'm trying to do is below:
class Program
{
public static Dictionary<string, int> teamInformation = new Dictionary<string, int>();
static void Main(string[] args)
{
runserver();
}
static void runServer()
{
//connection stuff
while(true)
{
threadRequest = new Handler();
Thread t = new Thread (() => threadRequest.clientInteraction(connection));
t.Start();
}
}
class Handler
{
public void clientInteraction(Socket connection)
{
//does stuff
teamInformation.Add(pTeamName, 0); //where pTeamName has been read from the client input
}
}
How would I go about making changes to the Dictionary (which needs to be accessible by all threads) in the Handler class?
I don't know how to index the threads either or at least flag them in the dictionary entries. I'm having trouble figuring out a way to send a specific value to a specific thread.
Starting with .NET 4.0 collections have a better handle on thread safety. You can have many threads write to them with no problems. (https://msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx). The same goes for multiple readers.
The problem lies when you have both operations happening at the same time as enumerating through a collection that gets modified is a problem.
A better alternative would be to use a datatype that supports thread safety such as ConcurrentDictionary which is thread safe and allows readers and writers at the same time. (Excludes some members accessed through interfaces that ConcurrentDictionary implements).
The change is most likely a drop in change for you from:
public static Dictionary<string, int> teamInformation = new Dictionary<string, int>(); to public static ConcurrentDictionary<string, int> teamInformation = new ConcurrentDictionary<string, int>();
See https://msdn.microsoft.com/en-us/library/dd287191(v=vs.110).aspx for greater depth
EDIT: Here is an example of it's usage:
using System;
using System.Collections.Concurrent;
using System.Threading;
namespace SO
{
public class Program
{
public static ConcurrentDictionary<string, int> teamInformation = new ConcurrentDictionary<string, int>();
static void Main(string[] args)
{
Start();
Console.WriteLine("ConcurrentDictionary contains : " + teamInformation.Count);
Console.ReadKey();
}
static void Start()
{
for (var i = 0; i < 10; i++)
{
var threadRequest = new Handler();
var thread = new Thread(() => threadRequest.ClientInteraction(teamInformation));
thread.Start();
}
}
}
public class Handler
{
public void ClientInteraction(ConcurrentDictionary<string, int> teamInformation)
{
for (var i = 0; i < 10; i++)
{
teamInformation.AddOrUpdate(Guid.NewGuid().ToString(), i, (key, val) => val);
}
}
}
}
As the ConcurrentDictionary is thread safe you can just pass it right to your thread. This code simply spawns a load of threads and creates a new entry for each.
However by using AddOrUpdate you can specify that if your key (or team) exists you can update the existing entry with the third Func param.
Other options for sharing the property would be through a static class or singleton. You may want to consider what will be using this property and your current architecture to see where to slot it in.
You could put the dictionary as paramter in the start function like:
Thread t = new Thread (() => threadRequest.clientInteraction(connection));
t.Start(ref teamInformation);
https://msdn.microsoft.com/en-us/library/6x4c42hc%28v=vs.110%29.aspx
Important is to use call by reference so you can access the same dictionary and not a copy. But im not sure if the compiler will accept the 'ref' here

How can I access a member from another class with a Timer?

I'm currently writing a class to calculate the average download speed over a defined period of time, taking a defined number of samples. The way I thought this would work is that this class runs a Timer object, which calls a method inside said class that will look at the bytes downloaded (maintained in a parent class, the FTPDownloadFile), and then store that sample in a Queue. My issue is accessing the number of bytes downloaded, however.
My method of accessing that information was through a reference that was passed in when the download calculating class was constructed, however, it seems like I'm not understanding/using references correctly. The variable that is passed in always appears to be 0, even though I can see the original variable changing.
Can anyone tell me what I'm doing wrong / suggest a better way for me to accomplish what I want to do?
First, here is the class that is handling the calculation of the download speed:
public class SpeedCalculator
{
private const int samples = 5;
private const int sampleRate = 1000; //In milliseconds
private int bytesDownloadedSinceLastQuery;
private System.Threading.Timer queryTimer;
private Queue<int> byteDeltas = new Queue<int>(samples);
private int _bytesDownloaded;
public SpeedCalculator(ref int bytesDownloaded)
{
_bytesDownloaded = bytesDownloaded;
}
public void StartPolling()
{
queryTimer = new System.Threading.Timer(this.QueryByteDelta, null, 0, sampleRate);
}
private void QueryByteDelta(object data)
{
if (byteDeltas.Count == samples)
{
byteDeltas.Dequeue();
}
byteDeltas.Enqueue(_bytesDownloaded - bytesDownloadedSinceLastQuery);
bytesDownloadedSinceLastQuery = _bytesDownloaded;
}
/// <summary>
/// Calculates the average download speed over a predefined sample size.
/// </summary>
/// <returns>The average speed in bytes per second.</returns>
public float GetDownloadSpeed()
{
float speed;
try
{
speed = (float)byteDeltas.Average() / ((float)sampleRate / 1000f);
}
catch {speed = 0f;}
return speed;
}
That class is contained inside of my FTPDownloadFile class:
class FTPDownloadFile : IDisposable
{
private const int recvBufferSize = 2048;
public int bytesDownloaded;
public SpeedCalculator Speed;
private FileStream localFileStream;
FtpWebResponse ftpResponse;
Stream ftpStream;
FtpWebRequest ftpRequest;
public List<string> log = new List<string>();
private FileInfo destFile;
public event EventHandler ConnectionEstablished;
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator(ref bytesDownloaded);
}
public void GetFile(string host, string remoteFile, string user, string pass, string localFile)
{
//Some code to start the download...
Speed.StartPolling();
}
public class SpeedCalculator {...}
}
This is a common 'issue' with understanding 'ref' parameters in C#. You see, unlike C+, there are no real value references in C#.
In C++, when you pass-by-reference, you actually internally pass pointer to the variable. Therefore, you can have a class member variable of type "int&" that is actual reference to an integer stored elsewhere.
In C#, 'ref' or 'out' parameter works in a similar way, but noone talks about pointers. You cannot store the reference. You cannot have a 'ref' class member. Look at your class: the sotrage variable is of type 'int', plain 'int', not a reference.
You actually are passing that value by-ref, but then you copy it to the member variable. The 'reference' is gone at the point where your constructor ends.
To walk it around, you have to keep the actual source object, and either introduce a strong dependency, or a weak one by an interface, or do it lazy/functional way - by a delegate
Ex#1: strong reference
public class SpeedCalculator
{
private const int samples = 5;
private const int sampleRate = 1000; //In milliseconds
private int bytesDownloadedSinceLastQuery;
private System.Threading.Timer queryTimer;
private Queue<int> byteDeltas = new Queue<int>(samples);
private FTPDownloadFile downloader; // CHANGE
public SpeedCalculator(FTPDownloadFile fileDownloader) // CHANGE
{
downloader = fileDownloader;
}
public void StartPolling()
{
queryTimer = new System.Threading.Timer(this.QueryByteDelta, null, 0, sampleRate);
}
private void QueryByteDelta(object data)
{
if (byteDeltas.Count == samples)
{
byteDeltas.Dequeue();
}
byteDeltas.Enqueue(_bytesDownloaded - bytesDownloadedSinceLastQuery);
bytesDownloadedSinceLastQuery = downloader.bytesDownloaded; // CHANGE
}
//and in the other file
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator( this ); // CHANGE
}
In C#, every object (class MyObject) is passed by reference, or implicit pointer, therefore taking FTPDownloadFile by parameter and assigning it to a member variable does not copy it, it is truly passed by ref (on the other hand, values (int, decimal, ..) and structs (struct MyThing) are always passed by value, so your original _bytes = bytes made a copy of int). Hence, later, I can just query the
Ex#2: "weak" reference
public interface IByteCountSource
{
int BytesDownloaded {get;}
}
public class FTPDownloadFile : IDisposable, IByteCountSource
{
.....
public int BytesDownloaded { get { return bytesDownloaded; } }
.....
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator( this ); // note no change versus Ex#1 !
}
}
public class SpeedCalculator
{
....
private IByteCountSource bts;
public SpeedCalculator(IByteCountSource countSource) // no "FTP" information!
{
this.bts = countSource;
}
...
private void QueryByteDelta(object data)
{
....
bytesDownloadedSinceLastQuery = bts.BytesDownloaded;
}
The first example was quick and dirty. In general, we usually want the classes to know as least as possible about all other. So why should the SpeedCalculator know about the FTPDownloadFile? All it needs to know is the current byte-count. So I introduced an interface to 'hide' the actual source behind. Now the SpeedCalculator can take the value from any object that implements the interface - be it FTPDownloadFile, HTTPDownloadFile or some DummyTestDownloader
Ex#3: delegates, anonymous functions, etc
public class SpeedCalculator
{
....
private Func<int> bts;
public SpeedCalculator(Func<int> countSource)
{
this.bts = countSource;
}
...
private void QueryByteDelta(object data)
{
....
bytesDownloadedSinceLastQuery = bts();
}
// and in the other file
private int getbytes() { return bytesDownloaded; }
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator( this.getbytes ); // note it is NOT a getbytes() !
}
// or even
public FTPDownloadFile()
{
bytesDownloaded = 0;
Speed = new SpeedCalculator( () => this.bytesDownloaded ); // CHANGE
}
The example with an interface is pretty, but the interface was 'small'. One is ok, but sometimes you'd need to introduce dozens of such one-property or one-method interfaces, it gets somewhat boring and cluttering. Especially if all of that is 'internal implementation' that anyways isn't published for any other people to use. You can very easily drop such small interface with a short lambda, as in the third example. Instead of receiving and storing a object-that-implememts-an-interface, I changed the parameter to Func. This way I require to get "a method that returns an INT". Them, I pass the some method. Note that during new SpeedCalculator, I do not call the this.getbytes(), I pass the method without parenthesis - this causes the method to be wrapped into Func delegate, that will be later invoked as bts(), and will return current counter. This getbytes is rarely used, only in this one place - so I can even drop it completely and write anonymous function right at the point of constructor call, as you can see in the "or even" part.
However, I'd suggest you to stick with interfaces for now, they are much clearer to read and understand.

Creating class instances at run-time and initializing simultaneously

I am attempting following code to create multiple instances of a class at run-time and want to initialize also, but it is giving error:
A local variable named 'inum' cannot be declared in this scope because
it would give a different meaning to 'inum', which is already used in
a 'parent or current' scope to denote something else.
public class MyClass
{
static int i=0;
class A
{
public A()
{
}
}
public static void Run()
{
string inum = "i";
for (int j=1;j<=5;j++)
{
inum = inum + j.ToString();
//Initialize Instance
A inum = new A();
}
}
}
You appear to be trying to use variable names "dynamically". That doesn't work in C#, and you should change how you think about variables. If you want to create several instances, declare an array:
public class MyClass
{
static A[] instances;
class A
{
public A()
{
}
}
public static void Run()
{
instances = new A[5];
for (int j=0;j<5;j++)
{
instances[j] = new A();
}
}
}
You cannot have dynamic variable in c#. The append you are trying is appending the value not the variable pointer.
rather use this way
Dictionary<int, A> inum = new Dictionary<int, A>();
for (int j=1;j<=5;j++)
{
//Initialize Instance and add to dictionary
inum.Add(j, new A());
}
You can get them by key name. There are several other way to store instances as collection
I'm not a C# programmer by any stretch of the imagination, but by the rules of Java and any other similarly syntaxed language I know anything about, what you are doing is attempting to redeclare 'inum' with a new type, after it has been declared as a string in the same scope.
The other point is that even if this were not the case, you are not creating multiple instances but filling the same variable with a new instance 5 times, which would only result in one instance (the last one).
From quickly reading a C# tutorial I think this is something like what you want. I'm not sure what you were trying to do with the 'inum' variable so it is gone, as is static variable 'i':
public class MyClass
{
class A
{
public A()
{
}
}
public static void Run()
{
// Declare array to hold instances
A[] instances;
// instances is now five elements long
instances = new A[5];
for (int j=0;j<5;j++)
{
//Initialize Instance
instances[j] = new A();
}
}
}
That should result in an array of 5 objects called 'instances' in the scope of the Run method - you may want this in the scope of the class itself, possibly as a static property.
As a side note, it's good practice to start at 0, not 1, for operations like this (with the var 'j') and the above code reflects this.
you cannot call the variable of type A "inum" (there exists already one called like that)
you have to give it another name like:
A anyOtherName = new A();
try to name the variable A with different name
A objA = new A();

Categories