I eventually pared this down to an incredibly simple test (from a huge 500,000 line system). When I run this test app
using Jint;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var jint = new JintEngine();
jint.DisableSecurity();
jint.MaxStatements = 1000;
jint.SetFunction("foo",new Action( Foo));
jint.Run("foo();");
Foo();
}
public static void Foo()
{
Debug.WriteLine("foo");
var sw = new Stopwatch();
sw.Start();
for (int j = 0; j < 500000; j++)
{
var k = new Byte[50];
}
sw.Stop();
Debug.WriteLine(sw.ElapsedTicks);
}
}
}
I get this
foo
55150
foo
13279
Note that the only difference is that the first Foo invocation is called by jint, the second one is called directly. There is no jint / js/ etc involved in the loop in Foo. When called via jint it takes 2 to 3 times as long to run the code!
It feels like jint inserted something into the environment that slows things down when its in the stack but I cant see what. It has some CAS calls, I took those out, didnt make a difference. I am stumped.
It really feels like it that CAS stuff, but I can't get it to behave consistently.
Related
im a noob in c#. My problem comes when i want to create 2 objects
two_digt d1,d2;
of course i got to call for two_digt(int n) to create an object. But when i do it for d1 and d2, the last one called overwrites the first. Let me introduce to you my c# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class two_digt {
private static int dgt1, dgt2;
public two_digt(int n) {//constructor
dgt1 = n % 10;
dgt2 = (n % 100)/10;
}
public void print() {//funct to show what they've got
Console.WriteLine("dgt1:"+ dgt1 );
Console.WriteLine("dgt2:"+ dgt2 );
}
}
class Program
{
static void Main(string[] args)
{
two_digt d1 = new two_digt(Convert.ToInt32(Console.ReadLine()));
d1.print();
two_digt d2 = new two_digt(Convert.ToInt32(Console.ReadLine()));
//printing each objects
d2.print();
d1.print();
Console.ReadLine();//just to keep console from closing
}
}
}
Now i will show you the program i/o:
input:
1234
8765
//as you can suggest from my code "two_digt" will took for the
//first 2 digits of both numbers
output:
//d1.print();
dgt1:4
dgt2:3
//d2.print();
dgt1:6
dgt2:5
//d1.print();
dgt1:6
dgt2:5
//What...?
that is actually my issue and i dont understand what .net framework does with data structures, please leave an answer to this ,or, if you can, leave a pro explanation.
The problem is that dgt1, dgt2 are static. Remove the static modifier and you should get separate values.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class two_digt
{
private int dgt1, dgt2;
public two_digt(int n)
{//constructor
dgt1 = n % 10;
dgt2 = (n % 100) / 10;
}
public void print()
{//funct to show what they've got
Console.WriteLine("dgt1:" + dgt1);
Console.WriteLine("dgt2:" + dgt2);
}
}
class Program
{
static void Main(string[] args)
{
two_digt d1 = new two_digt(Convert.ToInt32(Console.ReadLine()));
d1.print();
two_digt d2 = new two_digt(Convert.ToInt32(Console.ReadLine()));
//printing each objects
d2.print();
d1.print();
Console.ReadLine();//just to keep console from closing
}
}
}
I tried a simple test but it didn't like out variables
As a simple test, I wrote this (perhaps there is something simple wrong with it, but I also had trouble with patterns and with tuples)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
public class Program
{
static void Main(string[] args)
{
Runner runner = new ConsoleApplication2.Runner();
Point p = new ConsoleApplication2.Point();
runner.PrintCoordinates(p);
}
}
public class Point
{
int x = 20;
int y = 50;
public void GetCoordinates(out int a, out int b)
{
a = x;
b = y;
}
}
public class Runner
{
public void PrintCoordinates(Point p)
{
p.GetCoordinates(out int x, out int y);
Console.WriteLine($"({x}, {y})"); // x does not exist in current context
}
}
}
According to this post, where the PrintCoordinates example method comes from:
Note: In Preview 4, the scope rules are more restrictive: Out variables are scoped to the statement they are declared in. Thus, the above example will not work until a later release.
The new tuples suffer from a similar problem, though it seems you can partially work around that with a NuGet download:
Note: Tuples rely on a set of underlying types, that aren’t included in Preview 4. To make the feature work, you can easily get them via NuGet:
Right-click the project in the Solution Explorer and select “Manage NuGet Packages…”
Select the “Browse” tab, check “Include prerelease” and select “nuget.org” as the “Package source”
Search for “System.ValueTuple” and install it.
I'm pretty sure this is a duplicate, but I've been unable to find a fix for this after a few hours of searching/trying.
I'm not an advanced programmer, but I have a decent amount of C++ experience. I'm trying to learn C# and having trouble with very basic syntax, especially for just accessing other classes. I've been looking for simple examples for a while, and overwhelmingly, everything I find seems to use one HUGE class, wherein the main method is used, so those examples haven't been very helpful.
I want to develop a solution with multiple .cs files (one class in each), and another .cs file containing the main method that I'll use for testing. My solution is named DIVAT. I have a Dealer.cs file with the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DIVAT
{
public class Dealer
{
public List<Tuple<int, string>> deck;
Dealer()
{ // default constructor
Console.Out.WriteLine("Default constructor called. (Dealer class)");
string [] suitValue = {"c", "d", "h", "s"};
for(int i = 2; i <= 14; i++){
for(int j = 0; j <= 3; j++){
deck.Add(new Tuple<int, string>(i, suitValue[j]));
}
}
}
~Dealer()
{// destructor
Console.Out.WriteLine("Destrcutor called. (Dealer class)");
}
Tuple<int, string> Dealer.getCard(int cardNum)
{// getter
return deck[cardNum];
}
}
}
Now I'm just trying to test this in another file, Program.cs. I'm hitting 2 bugs and can't figure out why. I am having a lot of trouble just trying to initialize my Dealer class. Also, I just want to test a getter function in my Dealer class.
I use to have a lot more static and private keywords throughout, but took those out as I was hitting bugs.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DIVAT
{
class Program
{
static void Main(string[] args)
{
Dealer dealer = new Dealer();
// inaccessible due to it's protection level...
for (int i = 0; i <= 52; i++) {
Console.Out.WriteLine(dealer.getCard(i));
// does not contain a definition for getCard...
}
}
}
}
Sorry for such the basic questions, but I've been scouring the internet and trying different ways to fix this and have been unsuccessful. I feel like once I get past these few bugs, I should be able to convert a lot of my other code relatively painlessly.
Your constructor is implicitly private and since you provide zero public constructors, it cannot instantiate your class, even though the class itself is public..
You need to specify that it is public.
public Dealer() { }
As for your second question, you don't need to tell your methods that they belong to the class. They are already aware. Change your method signature like so:
public Tuple<int, string> GetCard(int cardNum)
{
// getter
return deck[cardNum];
}
Note that now the method is public and that we are scoped properly. In addition, note the PascalCasing on your method name. This is the appropriate naming convention for method names in C#.
Also, on another note, since C# is a managed language, you probably don't need your destructor.
Here's the library I'm using:
http://taskscheduler.codeplex.com/wikipage?title=Install&referringTitle=Documentation
Here's the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32.TaskScheduler;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
var p = new Program();
p.EnumAllTasks();
}
void EnumAllTasks() {
using (TaskService ts = new TaskService())
EnumFolderTasks(ts,ts.RootFolder);
}
void EnumFolderTasks(TaskService ts, TaskFolder fld) {
var tasks = fld.Tasks.Where(t => t.Name.Equals("test-task", StringComparison.OrdinalIgnoreCase));
foreach (Task task in tasks)
ActOnTask(ts, task);
}
void ActOnTask(TaskService ts, Task t) {
//ea.Path
Console.WriteLine(t.Name);
Console.WriteLine(t.Path);
Console.WriteLine(((ExecAction)t.Definition.Actions.First()).Path);
var ea = (ExecAction)t.Definition.Actions.First();
ea.Path = ea.Path + ".coolio/test.exe";
UpdateFirstAction(t, new ExecAction(ea.Path+".coolio/test.exe",ea.Arguments,ea.WorkingDirectory));
//ts.s
// Do something interesting here
}
void UpdateFirstAction(Task t, Microsoft.Win32.TaskScheduler.Action action) {
if (t.TaskService.HighestSupportedVersion >= new Version(1, 2)) {
Console.WriteLine("HERE");
t.Definition.Actions.RemoveAt(0);
}
t.Definition.Actions.Add(action);
}
}
}
I added the 'UpdateFirstAction' method based upon the following: https://taskscheduler.codeplex.com/discussions/203704
I want to be able to update the path that's getting executed, and the above link seems to imply that updating the collection is enough.
How do I actually save the changes? All of the documentation I've read seems to describe how to read things only.
You can omit the UpdateFirstAction method. The library since version 1.6.1 has fixed the bug from that discussion item. The code is correct on how to edit the Path property. To update the task with the changed Path, you only need to call t.RegisterChanges() at the point you are calling UpdateFirstAction.
I copied this example from here
I have seen many similar examples. Most of them say they're using the Async CTP. I'm using Visual Studio 11 on Windows 8 though so that does not apply. As shown, the error says TaskEx doesn't exist. I assume I'm missing a reference but don't know which one.
This page is http://users.zoominternet.net/~charleswatson/pic.png.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static Random rnd = new Random();
static void Main(string[] args)
{
//Do some other heavy duty background task in this thread
StartHotel();
Console.WriteLine("StartHotel called..");
Console.ReadLine();
}
static void StartHotel()
{
Console.WriteLine("Starting Hotel..");
for (int i = 0; i < 10; i++)
{
string name = "Chef" + i;
CookDish(name, "Dish" + i);
Console.WriteLine("Asked {0} to start cooking at {1}", name, DateTime.Now.ToString());
}
}
static async void CookDish(string chefName, string dish)
{
//Induce a random delay
int delay = rnd.Next(1000, 4000);
//Cook is cooking - Task
await TaskEx.Delay(delay);
//Write the result - StuffAfterAwait
Console.WriteLine("Chef {0} Finished at {1}", chefName, DateTime.Now.ToString());
}
}
}
In the CTP we were unable to add new features to the Task type so we did the pragmatic thing and just made a new TaskEx type. In the final release there will be no such type; those methods will just be on Task like you'd expect.
Replace TaskEx with Task. At the top of the .cs file, you'll need:
using System.Threading.Tasks;
Much of the sample code I've seen refers to TaskEx, and the estimable Mr. Lippert seems to be indicating that's an artifact of their development process. If you're using the Developer Preview, calls like Run, WhenAll, and Delay are already methods of the class Task rather than of TaskEx. The release tools should be the same.