In a splash screen for an iOS app written in MonoTouch C# I am calling a number of web services which then calls another web service until all the data I need has been collected for the app to run. I am doing this asynchronously so that I can display an activity indicator to the user.
However I feel like the code is very messy and all these calls and callbacks are in the ViewController. I would like a way of separating this so that the ViewController only cares about the results coming back but I would need a way for the ViewController to stop until the call has completed.
At the moment, my code looks a little something like this:
protected void FirstServiceCompleted(object sender, FirstServiceCompletedEventArgs e)
{
// Do something
_servicesHelper.GetSecondService(GetSecondServiceCompleted);
}
protected void SecondServiceCompleted(object sender, SeconServiceCompletedEventArgs e)
{
// Do something else
_servicesHelper.GetThirdService(GetThirdServiceCompleted);
}
... etc
It would be nice to have a way which through another object my ViewController retrieves the data from the event args while behind the scenes I use this code. At the end of all these calls I change to a new view to show the main home screen with this data populated. However my ViewController seems very bloated and there's a lot of repetitive calls like this.
Any help or advice would be very much appreciated.
I think it might be useful for you to look at the TPL - Task Parallel Library - this tackles exactly the sort of async processing you are talking about.
Using Task along with ContinueWith and WaitAll, I'm sure you'll find a way to clean up your code flow.
If you search you'll find hundreds of getting started links for this - eg http://www.codeguru.com/columns/experts/article.php/c17197/Understanding-Tasks-in-NET-Framework-40-Task-Parallel-Library.htm
Built on top of the TPL, in the near future you will also be able to use the new await/async features of c# - but these aren't available today for MonoTouch.
Related
I am working on Windows Forms application, that needs to start a big amount of async tasks. In other words, a small control panel, that will start and monitor the process (Task), started from this UI control panel.
But, after some researches, I realized, that there is no easy way to monitor variables' values from inside the Task.
Currently, I am looking for any way of monitoring progress in Task<>. Thinked, that I might start minimized process (Just basically copy&paste the whole code from task, that I need to start to a ConsoleApp, but, as always, that is not easy to catch the data from variables).
Any thoughts, how to do it correctly?
And found IProgress interface, but I didn't actually get the idea how it works. Just no examples.
Is there a way to add a canvas (or anything that can render a c# application, more specifically a game such as Tetris) to an MVC view?
I would like to make a game, add it to a view, and send the score of the client to the server to process rewards and other stuff.
I have no idea how to get started, can someone show me the way please?
I would prefer to not use JavaScript for this, I would like a server based application.
Sorry, but you're going to need to use JavaScript since the API for canvas is written in it.
Another issue you're having, I think is you data layering. Which will eventually look like this:
C# Server <- Javascript Events -> Canvas View
Basically Javascript will call async methods to your server every so often, either getting data (current high scores) or sending data (giving new scores). In turn it will update the canvas view. Also, everything that happens to the canvas will be handled in JavaScript through its event handling system. These event handles can trigger other events like calls to the server or a local event like the current falling block to rotate.
I don't see away around JavaScript being a huge part of this, since you can't really do a real time game without a lot of it being client side, at least in a web based game.
I'm wondering what the best approach might be for what I'm trying to do. My application has a button that starts a background download operation, and then performs some actions dependent on the downloaded files.
It's like a "The game will begin shortly once necessary data is downloaded" situation, where the user may still use the main form.
private void btnStart_Click(object sender, EventArgs e)
{
//execute some code
Downloader.RunWorkerAsync(files); //this worker reports progress to the main form
while (Downloader.IsBusy)
Application.DoEvents();
//execute some more code
}
I'm aware that doing it that way is not good at all.
I cannot execute the download code synchronously, because the main form needs to remain responsive during the download operation.
I also cannot put the final code into the download completed event, as it is used by many other areas of the program and must remain a "generic" download system.
So, is there a way to do what I want? I do not have any experience with other async methods.
If you use BackgrounWorker you must configure it properly. BW has RunWorkerCompleted event to which you must subscribe to handle completion of you async work.
I think you should use asynchronous programming features of the .net 4.5 framework (await and async).
refer to async programming
I am designing a website and it uses Windows Forms (in Visual Studio 10) in which for example i have five-six URLs. Now i am displaying them on home page of my website xyz.com
What i want is, i want to calculate total no. of tweets for all links and display links based on no. of times they are being tweeted/retweeted.
for a url we can calculate no. of tweet using twitter api http://urls.api.twitter.com/1/urls/count.json?url=YourURL
I know all the stuff like receiving JSON values in a string and parsing json to retrieve tweet counts and then compare and display links based on the priority etc.
What i have been using till now it is initiating all the process using a Click_Button.
But i want to know how can i automate this all for each 10 minutes. Its like a end user can see urls priority with just refreshing the page.
One way to do this is to run a scheduled task ever 10 mins which interacts with the DB. The web application also interacts with the DB and thus the two systems are distinct.
Side note: it is strongly recommended to use only console applications as scheduled tasks. If you make a windows form application will will have some issues.
As Kieren Johnstone has pointed out in another answer the best way to do this would be to write a windows service.
I still recommend the solution as described above as a first step since it is easy to debug and test.
Additionally, give some serious consideration to logging and error reporting -- with background tasks you can never know to much about what the heck it was doing when it broke.
If timing itself is not important (it doesn't have to be 10 minutes precisely), I would suggest binding to any event that fires when users use your application. No point in calculating anything if noone is using it :-)
So you could use a login, or page load, or whatever happens at an interval roughly like the interval you wish to achieve.
You can always store a DateTime variable somewhere that you can check to see when the calculation was last made. Something like:
public void MyEventHasFired()
{
DateTime dateLastProcessed = ... //Database? Session data? Anything goes.
if(dateLastProcessed < DateTime.Now.AddMinutes(-10))
{
//calculate
...
dateLastProcessed = DateTime.Now;
}
}
The best solution is definitely a Windows Service. It can be started, stopped and managed well, it's easy to log, maintain..
Scheduled Tasks are very prone to problems. At least in a Windows Service you can configure it to start automatically, re-start if there's a problem, you can control the timing yourself in the code, and catch/handle exceptions as you wish.
The best scheduler i know is Quartz.net
It'is not simple to use but it works great.
You can find an example with asp.net there http://blogs.planetcloud.co.uk/mygreatdiscovery/post/ASPNET-Scheduled-Tasks-with-QuartzNET.aspx
Anyway i agree with Kieren Johnstone: you should use a windows service
I'm trying to figure out a way to make user controls run in their own UI threads. Is this possible? I'm trying to prevent a module-based application from crashing due to a single module.
Any thoughts?
That's not possible. However, with some non-trivial code, you can have different windows running in separate threads. Each window will have its own message loop.
Update:
Another way you could think of is to write your controls in a special way. You can handle all events in your controls by creating a new thread that will run all the logic.
Unfortunately all UI controls run on the same UI thread. Therefore any code running on this thread that could potentially lead to a hang situation would need to be coded with some sort of timeout logic.
DateTime startTime = DateTime.Now;
while(DateTime.Now.Subtract(startTime).TotalSeconds < 30)
{
//do something
}
Otherwise, as Orlangur stated earlier, all event handler code would need to be run in separate threads. You would still however need to monitor these threads to determine if they've been running too long and shut them down. As such you might as well implement the type of logic above as it would be a lot less work and more maintainable.
I suppose it's not a matter of the program crashing. Exceptions can be caught of course, but the issue is in hanging controls. For the sake of this situation, here's an example:
public void Button1_Click(object sender, EventArgs args)
{
while(true) {}
}
If this code were to run in a control, an exception wouldn't throw, but it would hang. I'm trying to determine a way to catch this and remove the control module from the application.
Running controls in different threads should be possible. A little hacking and windows overrides and it should be doable.
I am thinking you can create a GUI control in another thread, then move it to a common window (main gui thread) with the win api SetParent. SetParent can be used to "hijack" other windows, so you should be able to grab the controls this way. But of course there might be focus issues and other issues, but might be doable.
I used that once to put my own button onto MS Messenger.