I have read many articles on .Net 4.0 threading. I have yet to understand how it will apply to my situation.
I have a .Net 4.0 application that is a chat bot for a game. It listens to users that can interface with the bot by typing an ! and the command. For Example: !online will run the code that will return the list that the users are online.
This is a plug in system, so when a command is detected, every plugin has a public void OnFirehandleCommand(object botArgs) available. Inside the code, I can determine if that specific command is for that plugin or not. Then the code is executed.
The problem in the past is that the application will not process another command until the code for that command is finished. Some commands may take anywhere from a few seconds to 4 minutes to finish.
In order to remedy that, I attempted to use multithreading at the entry point where a command is requested by the user. I am using the following code:
botArgs = new BotArgs {Bot = bot, Args = args};
var thread = new Thread(OnFirehandleCommand);
thread.Start(botArgs);
That is the extent of the threading that I use. This fires each time a command is given. However, this seems to be lacking any control at all, and as you see a new thread is generated each time a command is received.
Is there a better way that I can use multithreading for this situation? Are there any examples for a situation like this?
Try tasks :
var task = System.Threading.Tasks.Task.Factory.StartNew(
() => OnFirehandleCommand(botArgs));
Related
I am using a 3rd party rest api to query data and display it in my app. I have to perform a task like at night 12 approx. it will perform a background task to query data from rest api and update live tile and generate notification. I would like to use only C# only for this task. I don't know what will be best approach to do this task. But I using below code to perform background task to do this which is not working. Not sure why?
BackgroundTaskBuilder taskBuilder = new BackgroundTaskBuilder();
taskBuilder.Name = taskName;
SystemTrigger trigger = new SystemTrigger(SystemTriggerType.InternetAvailable, false);
taskBuilder.SetTrigger(trigger);
taskBuilder.AddCondition(new SystemCondition(SystemConditionType.InternetAvailable));
taskBuilder.TaskEntryPoint = typeof(BackgroundTask.BackgroundTask).FullName;
taskBuilder.Register();
and from background task I am querying data and generating toast notification.
Any help why this code is not working or when this task will fire. Is there any better approach to do above task?
Thanks
Regarding the code you have not working...
For Windows Phone 8.1 unlike Windows 8\8.1, you are required to call BackgroundExecutionManager.RequestAccessAsync() (search MSDN\internet) for ANY background task before registering task(s) whereas in Windows this is only required for some tasks. Make sure your code calls this and validate the returned value before registering your background task(s).
Regarding knowing if your task "worked"...
It's a good idea to have the background task implementation run (IBackgroundTask::Run()) independent of the trigger\conditions you've set to ensure it performs without issue by debugging it. See instructions in the following link: http://msdn.microsoft.com/en-US/library/windows/apps/xaml/jj542416.aspx.
Regarding your use of SystemConditionType.InternetAvailable...
I'm not 100% about this but I'm pretty certain this will be redundant given you already have a SystemTriggerType.InternetAvailable. I don't know of a situation where the trigger would fire but the condition wouldn't be true.
Regarding the requirement you've mentioned...
If I understand your requirement correctly you have different options here:
If your app is a Windows Phone XAML app that need to run based on time, I would recommend either TimeTrigger or MaintenanceTrigger triggers (as opposed to the SystemTrigger). These are both Background Tasks. For general info on Background Tasks and links to the TimeTrigger and MaintenanceTrigger documentation see this MSDN link: http://msdn.microsoft.com/en-US/library/windows/apps/xaml/hh977056.aspx.
If your app is a Windows Phone Silverlight 8.0 app you can use Background Agents, specifically either PeriodicTask or ResourceIntensiveTask. See the links posted by others or search the MSDN\internet for more info.
If your app is a Windows Phone Silverlight 8.1 app you can use the option in either 1 or 2 above.
I think you should try using PeriodicTask. Also consider the constraints mentioned in the link.
create one class with output Type :Windows Runtime Component
and put your Class that inheritance from IBackroundTask so this work
if you use from emulator for launching app, i think your app for register task not active in emulator.
I've a set of queries which I want to execute only once in day, I know this is possible using TaskScheduler in C#. But I am not getting any example suitable for my requirements. Can anybody give a example code for this?
You can try FluentScheduler. The documentation has the sample codes all you need. Firstly I thought it is for web only, but now I think you can use it for using with Desktop Application too. But not sure and not tested.
https://fluentscheduler.codeplex.com/documentation
EDIT You can also use Task Scheduler -
First create a console application that can run and do all your tasks. You can even invoke other processes with it. Then build the executable and save it in a safe location.
Then go to Administrative Tools > Task Sheduler And create a new task by clicking Action > New Task. You will see a screen like this -
Select your executable and other permissions there.
Now to run it in schedule move to next tab 'Triggers' and click add at the bottom. You will see a screen like this -
Now add your desired schedules. Make sure you use logs, because you will not be able to see the outputs directly. Either you can use windows event viewer or write to custom text file for your convenience.
Task Scheduler is a part of windows itself. It does not have a
dependency on C# or C++ anything. Basically you tell windows that it
will run the specific program at a regular schedule. It is the job of the
executed program to initialize all environment and execute appropriate
code. So even if you use task scheduler you have to make sure that the
program you are using to run with it, has all other options and codes
right.
The Timer is probably the best solution for you.
var timer = new Timer {AutoReset = true, Interval = 30000}; 1s = 1000ms
timer.Elapsed += timer_Elapsed;
timer.Start();
.......
public void timer_Elapsed(object source, System.Timers.ElapsedEventArgs e)
{
// do stuff here that will execute every 30 seconds
}
If you need a reliable scheduler, writing your own from scratch might take more effort than expected. What if the machine gets rebooted? What if it happens 10 seconds before execution time? Should the task be executed late or not at all? Where will the data be persisted? You have to think about all these things.
Alternatively, you could use Quartz.NET. It is a C# port of popular Java job scheduling framework. The codebase is well tested and robust. Have a look at it here:
http://www.quartz-scheduler.net/
I am still pretty much new to c# so you will have to bear with me.
I have developed a windows form program which updates some SQL records as an end of day process for one of our clients.
The next step is that I need to install the program on a server and simulate a button click in the program to become a scheduled task.
I know how to setup the task on the server side where you start program and enter the arguments. But I am unsure as to what code I need to include in my program to achieve this.
Consider using Windows Task Scheduler.
You could extract your business logic to a separate DLL and write a simple Console app that will just run your task after accepting the parameters through command line.
My recommendation would be to get away from running a GUI-based/windowed application from a scheduled task - this is generally madness in practice. Ideally, deploy a console-based version of your application that requires execution (perhaps with parameter arguments) and doesn't require any user (or quasi-user-) interaction.
If you simply can't create a 'system version' of your application, then I guess you have two choices, both immensely ugly: 1) create some kind of macro script which is executed instead of your program, this script could execute the program and issue 'the click', 2) perform 'the click' on startup of your application by invoking the button click handler (maybe based on a parameter to give it a duality in execution modes.)
I think you are also asking about command-line argument passing. See the answers to this question.
In particular, I highly recommend the accepted answer: NDesk.Options.
I have similar task to do making winforms as windows task. what i did is
in windows task scheduler in the task tab,under Run put your exe and then /Auto,it will run as schedule.
Example:winform.exe /Auto
If I'm understanding your question correctly, this is how you could possibly proceed:
Best way to parse command line arguments in C#? -> check the answers and choose a library to process the args or write your own code to do so.
Create a scheduled task if those arguments are present by Creating Scheduled Tasks
If it is a windows application, just go to the bin folder, get the executable file, and finally schedule a task for it by using windows schedule task and choose the exe file as you targeted application.
if it is web application, you may want to include your code in a quartz.net scheduled job, details are on quartz.net website.
Very popular solution is Quartz.NET http://quartznet.sourceforge.net/
Take a look in the Timer class
http://msdn.microsoft.com/en-us/library/system.timers.timer(v=vs.110).aspx
Why not extract your database update logic as a windows service
you can segregate the sql handling part in a separate DLL and use the common DLL for both your form application and the windows service.
A window service run in background and can be automatically started when the computer boots, can be paused and restarted, and do not show any user interface.
Moreover you need not to install any third party software for same and window service code base can be ported to any windows machine with required version of .Net Framework installed.
Add reference: Microsoft.Win32.TaskScheduler
then write this code:
using (TaskService ts = new TaskService())
Microsoft.Win32.TaskScheduler.Task task = ts.GetTask(TaskName);
task.Run(); //start
task.Stop(); //End
What I thought would be pretty easy is quickly defeating me. I'm not a native C# programmer, but was asked to create a WinForm application that has a single instance. I''ve seen the Mutex examples already on StackOverflow, but the one thing that eludes me is the ability to pass parameters to window on the command line, parse the values and repaint the form with the new values.
Anyone have an example of this? The main thing that seems to be tripping me up is the threading. I want to run my.exe and show the window. Each time the form is run, I don't want a new form -- just to get the new parameters and show them in the form.
Any/All replies are appreciated!
When you starting another instance of your application, you are running same code, but on different process. So, you need to look on passing data between processes. Something like Named Pipes or Remoting.
#lazyberezovsky is right. Invoking again the application from the command line will spawn a different, unrelated process and you would require inter-process communication to forward the new parameters to the previously running app instance, before quitting the new process being invoked.
IMHO, the easiest way (not the best certainly) to communicate between these two processes would be using the Windows Registry, as this is already thread-safe and the API is very simple.
First, when the application runs, before showing the main form, I would perform a check to see if another instance of the app is running.
If false, it is the first time the app runs and I would process the command line and show the form as regular. I would also clear the registry key used for inter-process communication (see below).
If true, then I would store the command line in the registry on a specific key that will serve for inter-process communication and then I would terminate the application without even showing the main form.
Your running application (the first instance) will require to start a polling mechanism (could be a Windows timer firing once each second) that regularly examines the registry key where a new command line is expected . It would normally find and empty string and do nothing, but if the retrieved value is not empty, then it would mean the user spawned again the application with a different set of parameters, then you can proceed to decode your command line and repaint the window as necessary. After this, make sure you clear the registry entry again, so the polling mechanism resumes and detects the next time the application is invoked by the user.
Named pipes, WCF, .remoting or TCP sockets are IPC mechanisms that can be used and won't require a polling mechanism, that may be frowned upon by some. ;)
Hope this helps!
I have a script I wrote in C# (part of a ASP.NET application) that would reset a number if the end date of a booking is reached. I would like to automate the process, so each time an end date of booking is reached, it will send an email notifying that period is expired and also execute my script to reset the counter.
I heard that Windows Scheduler could be used? I know cron is perfect for this job, but unfortunately it is windows of course I am using. Any hints on what to do for automation of tasks above would be greatly appreciated.
Go to:
Control Panel->Administrative Tools->Task Scheduler
Create a new task and specify date, time, frequency, etc.
Your C# program can be invoked from the task you created on the step above.
Usually, I either write a small C# console application or use C# Script for this. If I would understand the "strange" (IMHO) syntax of Powershell, this would be the preferable way to do.
No matter what you use, you usually cannot use C# code that is included inside an ASP.NET application. Instead, extract the code into one of the possibilities above and use the Task Scheduler to create a task with the following options:
Depending on your requirements, the scheduled task should be created to run with an administrative user.
Depending on your requirements, the scheduled task should have the “Run with highest privileges” checkbox set.
You could schedule the task to e.g. run every n minutes/hours, even if no user is logged in.