|
That doesn't make a lot of sense:
var INF = new IniFile(Path.Combine(Directories.OLD_DATAFOLDER, @"yt.txn"));
If it's a static class, you can't create a variable or an instance of it!
So either you will get a couple of error messages telling you that, and your app won;t compile; or it isn't a static class at all, and the problem is in the class constructor.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Hello Friend,
sorry for my long code and IniFile is not static. moreover, IniFile is not static.
Here is the exception report:
System.InvalidOperationException was unhandled by user code.
Additional information: The calling thread cannot access this object because a different thread owns it.
And the line where I am getting the code:
var INF = new IniFile(Path.Combine(Directories.OLD_DATAFOLDER, @"yt.txn"));
|
|
|
|
|
So look at the line, and there are two possible parts:
Directories.OLD_DATAFOLDER Which looks like an enum , but we can't see it. If it's an enum then its won't be that.
new IniFile(...); Which means it's in the constructor, which we can't see.
You've got a cross threading error in code we can't see which probably shouldn't be using threads and the fragment you show use doesn't use threading anyway.
That doesn't exactly make it easy for us to work out what your problem might be...
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
It would be much more helpful if you put only the relevant parts of the code, and showed the exact text of the error message.
|
|
|
|
|
And what error do you get? I have the suspicion that you're trying to access UI controls from this thread, but as you haven't told us what the exception is, we cannot say for certain.
|
|
|
|
|
Hello,
I would like to ask for a 'code review' of the project below, as I have never designed such a thing before and I wonder if there are any serious problems with the code/approach below.
Here's a little background - I create a bunch of small and mostly internal WPF applications for my company - usually for some file manipulation etc. For these programs, I would like to start collecting user info - who uses them, how often, most importantly - which version is used.
It's partly for my personal skill development, but I also want to introduce auto-updating for my apps - some of them have this feature already, but they rely on text files located on shared drive so obviously not a good solution.
The intended audience is not a large crowd, probably fewer than 50 users. The calls to the database will most likely happen only on the application launch.
The idea is that I have a generic 'helper' dll, which I reference in my projects so that in each of the programs I call a simple method and have the repetitive registration handling out of my mind. All the data is stored in a single Azure database called MyDB, and all the programs should connect through the same API (also hosted in Azure), called e.g. MyApi (myapi.azuresites.net).
So, looking from the point of view of a single client app:
public MainWindow()
{
InitializeComponent();
Register = new RegistrationHelper();
var progressInfo = new Progress<string>(p => StatusInfo = p);
Register.HandleRegistration(progressInfo);
}
Now, the helper library contains a smart constructor that will deduct all the info I need for my database (email is optional only for some programs with explicit registration):
private const string DefaultApiAddress = "<a href="https:
public RegistrationHelper(string email = null)
{
ApiUri = new Uri(DefaultApiAddress);
UserName = Environment.UserName;
MachineName = Environment.MachineName;
UserProvidedEmail = email;
CurrentAssembly = Assembly.GetEntryAssembly();
ProgramName = CurrentAssembly.GetName().Name;
ProgramVersion = FileVersionInfo.GetVersionInfo(CurrentAssembly.Location).FileVersion;
}
Then it has a public method for running handling the registration (which obviously should not block program execution):
public void HandleRegistration(IProgress<string> progressInfo)
{
Task.Run((() => HandleRegistrationAsync(progressInfo)));
}
Which calls a private handler:
private async Task HandleRegistrationAsync(IProgress<string> progressInfo)
{
try
{
progressInfo.Report("Connecting...");
RegisteredUserId = await GetUserIdAsync();
if (RegisteredUserId == 0)
{
RegisteredUserId = await RegisterUserByNameAsync();
if (RegisteredUserId > 0)
{
progressInfo.Report(string.Format("Newly registered. Id: {0}", RegisteredUserId));
}
else
{
progressInfo.Report("Registration failed");
}
}
else if (RegisteredUserId < 0)
{
progressInfo.Report(string.Format("Not registered. {0}", RegisteredUserId));
}
else
{
progressInfo.Report(string.Format("Updating user {0} info...", RegisteredUserId));
progressInfo.Report("Registered. Id: " + RegisteredUserId);
}
}
catch (Exception ex)
{
progressInfo.Report("Connection error");
if (ThrowExceptions)
throw ex;
}
}
And the methods that call the API are all pretty similar, structured as follows:
public async Task<int> UpdateProgramUsageAsync()
{
try
{
using (var client = new HttpClient())
{
client.BaseAddress = ApiUri;
client.DefaultRequestHeaders.Accept.Clear();
HttpResponseMessage response = await client.GetAsync(string.Format("api/update/{0}/{1}/{2}/", RegisteredUserId, ProgramName, ProgramVersion));
return response.IsSuccessStatusCode
? Convert.ToInt32(response.Content.ReadAsStringAsync().Result)
: -1;
}
}
catch (Exception)
{
if (ThrowExceptions)
throw;
else
return -666;
}
}
Now, what's in the web API:
There is a single UserController (apart from the stuff that comes out of the box from the WebApi template). It contains the connection string to the database (hardcoded), plus a bunch of constants for StoredProcedures names and stuff like that.
Then, my controller methods are structured as follows:
private const string ConnectionString = "allthestuffsensitivetoconnecttodatabase";
[Route("api/getid/{username}")]
public async Task<int> GetIdAsync(string username)
{
using (var conn = new SqlConnection(ConnectionString))
{
conn.Open();
if (conn.State == ConnectionState.Open)
{
var result = await ExecuteScalarCommandAsync(GetRegisteredUserByName, conn,
new[]
{
new SqlParameter(UserNameCol, username),
});
if (result != null && !(result is DBNull))
{
return Convert.ToInt32(result);
}
return 0;
}
}
return -1;
}
private async Task<object> ExecuteScalarCommandAsync(string commandName, SqlConnection conn, SqlParameter[] parameters)
{
using (var command = new SqlCommand(commandName, conn)
{
CommandType = CommandType.StoredProcedure,
})
{
command.Parameters.AddRange(parameters);
return await command.ExecuteScalarAsync();
}
}
Also, as for the methods that not only 'get' values, but also update database, I am using the GET as well.
The one below is a match of UpdateProgramUsageAsync() pasted above:
[Route("api/update/{userid}/{programname}/{version}")]
[AcceptVerbs("GET")]
public async Task<int> UpdateProgramUsageAsync(string userid, string programname, string version)
{
using (var conn = new SqlConnection(ConnectionString))
{
conn.Open();
if (conn.State == ConnectionState.Open)
{
var result = await ExecuteScalarCommandAsync(UpdateProgramUsage, conn,
new[]
{
new SqlParameter(UserIdCol, userid),
new SqlParameter(ProgramNameCol, programname),
new SqlParameter(VersionCol, version)
}
);
if (result != null && !(result is DBNull))
{
return Convert.ToInt32(result);
}
}
}
return 0;
}
As you can see, it relies on stored procedures updating the database and returning some response codes. The procedures are pretty simple (get value, put value into a table, nothing fancy).
modified 12-Sep-15 10:21am.
|
|
|
|
|
And your question is?
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Sorry - I was actually asking if it makes sense or are there any serious problems with the code.
|
|
|
|
|
... and?
Is there a question in that presentation you posted?
|
|
|
|
|
Sorry - I was actually asking if it makes sense or are there any serious problems with the code.
Silly mistake, I've edited the original post...
|
|
|
|
|
Hello,
I am new in algorithms and I am trying to be better. I have an problem to solve and I really need help with that.
I need to write a function that finds the zero-based index of the longest run(consecutive sequence of the same character) in a string. If there is more than one run with the same length, return the index of the first one.
Can someone help me to solve and understand this problem?
Thank you in advance.
|
|
|
|
|
Start by visualizing how you would solve the problem with your own brain. Then write down the steps you would follow.
Then, convert those step descriptions to code, and voila!
If you get stuck along the way, show the code you have written so far, and someone will help you.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Thank you, I finally solved it
|
|
|
|
|
Hello,
I have a question - I have a helper project which I use in all the applications that I create. It contains some extension methods and a bunch of generic helper classes, controls etc. I update /extend the helper project from time to time.
I tried two approaches for using it
1) add .cs files directly (Add as link) to each project where I use them
2) compile it as .dll and add it as reference
I see some benefits and drawbacks of these approaches.
The first one:
+ is simpler, because the helper classes get compiled into the exe file, therefore I can often very easily provide just a single .exe file that will work just fine. Because I add as link, I can be pretty sure that whenever I build any project that uses the helper, the helper files will be the latest version.
+ is even simpler, because I can separate the files, so that my extension methods that run fine on .NET 4.0 can be referenced separately from the ones that require .NET 4.5, which means that the app as a whole can run on .NET 4.0
- doesnt seem to be 'best practice'
The second one:
+ appears to be the right approach, but:
- requires me to deliver a separate .dll file, which for some reason is much more difficult for users (they tend to share my programs without the .dll, which then crashes on startup)
- as it gets compiled into a single .dll, it will require the highest version of .NET - many of my users don't have .NET 4.5 and only some elements of my helper class require this, which means I can be forcing some people to update their systems for no reason
- I also need to make sure that whenever I update any of my programs, I also deliver the .dll file - even though I don't know if it has been changed since the last version, or not (it could have been, but it could as well be the same version). I cannot see a simple way to determine that, without keeping track of assembly version, which is additional work. For now, when I update my programs, I only deliver updated exe, and I like to keep it small and low profile.
So, what is the actual benefit for using the .dll file here? Please note, that I am the only person editing code of all the applications and the helper files.
Thanks in advance for your opinions!
|
|
|
|
|
The second one is the right one: it means that you can fix bugs and release the latest version without having to rebuild the application(s) that use it. It also means that the "consumer" of the helper classes can't change the way they work and nobody knows.
Bartosz Jarmuż wrote: requires me to deliver a separate .dll file, which for some reason is much more difficult for users (they tend to share my programs without the .dll, which then crashes on startup)
So issue your application with a setup program - because that also makes sure that the correct version of the framework is installed. Would you copy "Word.exe" from one system to another and expect that to work?
Bartosz Jarmuż wrote: s it gets compiled into a single .dll, it will require the highest version of .NET
Why? It will need the highest version of .NET that will run the code within the DLL, not the version that your app uses.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Quote: Why? It will need the highest version of .NET that will run the code within the DLL, not the version that your app uses.
Hm, I was under an impression, that if I reference a .dll file into my project, and that .dll has code that requires .NET 4.5 then the whole app needs to be built for .net 4.5
As for the setup project, yeah, I started doing that some time ago (exactly because of .net auto-check), but it's quite a lot of additional work (create the project, set all properties etc), which is tiring for a 40kb program.
Quote: it means that you can fix bugs and release the latest version without having to rebuild the application(s) that use it. It also means that the "consumer" of the helper classes can't change the way they work and nobody knows.
What's the harm of rebuilding the app that uses it? As for the part about the consumer, you mean a scenario where I deliberately or accidentaly change the code of the helper files while working on a project that uses it? That would definately be a problem, but I suppose only in case if more than one person worked on it...
Thanks a LOT for your comments!
|
|
|
|
|
If your DLL is built for 4.5, then you app needs at least 4.5 as well.
But if your DLL is built for 2.0, then your app needs at least 2.0, but can use 3.0, 4.0, or 4.5 without any problems.
Bartosz Jarmuż wrote: What's the harm of rebuilding the app that uses it?
Change control.
Rebuilding a production app means change control to track who has what, who changed what, and why.
If you have added functions to the DLL, the exe that references it doesn't have to change.
Bartosz Jarmuż wrote: As for the part about the consumer, you mean a scenario where I deliberately or accidentaly change the code of the helper files while working on a project that uses it? That would definately be a problem, but I suppose only in case if more than one person worked on it...
Even if there is only one person, it's too easy to change something in a hurry - and then you end up not knowing which code you want. And you have to check which app has what code when you fix a bug in the "dll" code to make sure that you fix it there as well.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
|
You're welcome!
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Some other things you might want to throw into the mix.
Keep your helper code in its own project and for each client app have a solution that contains the helper project and the client app project, and the client project has a project reference to the helper project. That way your latest version of the helper is always compiled\included with the client app and you can make changes to both on the fly. When you next open a different client app solution it'll see all the changes you made to the helper. It's just an easier way of managing things so you don't have to worry about dll references.
Second you could maybe keep the helper assembly in the GAC so it is automatically found by client apps. That way updating the GAC on one machine means all your client apps see the helper. It also means you can distribute just the client exe and as long as the target machine has the helper in the GAC the client app will work. If you do this you'd need to be very careful that changes to the helper don't break other apps as they'll all be using it.
|
|
|
|
|
Quote: Keep your helper code in its own project and for each client app have a solution that contains the helper project and the client app project, and the client project has a project reference to the helper project. That way your latest version of the helper is always compiled\included with the client app and you can make changes to both on the fly. When you next open a different client app solution it'll see all the changes you made to the helper. It's just an easier way of managing things so you don't have to worry about dll references.
Hmm, actually that's one of the things I tried first - however, I got puzzled by the fact that I cannot do 'Add as link' in case of adding the project - so I thought I would lose the single central location of the project if doing so. However, I've checked now and it appears that if I add the project and edit it, the changes get updated throughout all the applications.
Thanks (actually, that's a third, different approach which makes me even more puzzled)
|
|
|
|
|
Actually if you add the reference to the entire project, then the project is not compiled into the app - it is still added as a separate .dll file.
|
|
|
|
|
Bartosz Jarmuż wrote: Actually if you add the reference to the entire project, then the project is not compiled into the app - it is still added as a separate .dll file.
I didn't say otherwise.
|
|
|
|
|
Over a decade of working with the .NET Framework, I've learned some hard lessons about developing and using helper classes. My rules of thumb for helper classes are simple and straightforward.
1) Target the lowest version of the framework that supports the method, defaulting to 2.0.
2) Segregate classes by target framework.
3) Keep helper assemblies out of the Global Assembly Cache.
I repeat: Stay away from the GAC. It's a sand trap. I've had no end of grief from putting assemblies into it.
First, everything that goes into the GAC must be signed with a strong name, which means that you must keep up with the key file and its passphrase.
Second, it adds a step to the installation, which requires you to either know the whereabouts of GACUTIL.exe on their machine, or ship a copy with your package.
Third, the GAC on the user's machine becomes cluttered with old versions of your assembly, which may have become obsolete. So, you have created for yourself another maintenance issue.
OTOH, if you put the helpers into one or more assemblies, each in its own project, then set a reference that points to the Release build of the assembly (in the /bin/Release directory of the project), it gets copied automatically into the /bin/release directory of your current project. If you change the satellite assembly, the next build of any project that has a reference to it gets a fresh copy. When you are ready to ship, everything you need to ship should be in the /bin/Release directory, which was the point behind the much-touted XCOPY install.
With respect to the routines that require the 4.5 framework and runtime, put them into a separate assembly, and set a reference to it only when your project actually uses one of them.
|
|
|
|
|
David A. Gray wrote: I repeat: Stay away from the GAC.
I agree with that. Always seemed to me to be a solution looking for a problem that didn't exist.
|
|
|
|
|