Skip to main content
Home Forums Silverlight Programming Programming with .NET - General Threading in Silverlight
15 replies. Latest Post by WilcoB on April 7, 2008.
(0)
vaibhavk
Member
0 points
2 Posts
05-03-2007 6:51 PM |
Hey guys, First off, am I correct in assuming that the browser loads pages using a single thread i.e. if you write a big for loop in javascript every other operation will hang until the loop completes. Silverlight has a System.Threading namespace, how many threads can I create with it? In one of the Mix session videos I heard that Silverlight uses the browser networking stack for any communication with the server. What are the limitations other than no support for cross-domain access. At this point I am waiting for the Orcas Beta 1 download to complete, just can't wait to get started on Silverlight.
Thanks,Vaibhav
toddreif...
24 points
05-03-2007 9:39 PM |
As you noticed, the System.Threading namespace is nearly 100% exposed in the 1.1 Silverlight alpha. As currently exposed, there are no limits on the number of threads that can be created by System.Threading except the normal memory limitations of the OS.
I am one of the software developers working on the final design of System.Threading and it has been somewhat difficult to filter what will be exposed in System.Threading when we consider that the client applications will be running in the browser and a number of operations (such as drawing the UI) can only reliably occur from a particular thread. This forces a complex code-pattern that neither the System.Threading classes nor the classes that allow browser or UI manipulation do not currently 100% enforce. For now, your best bet is to try to write your code in multiple threads (if it makes sense for your app), but be aware that some operations may need to be called from the original thread or controlled by some type of synchronization primitive to ensure that the engine's call to the browser does not expose an underlying thread-safety issue.
I envision some extremely powerful games that could be written in the browser by using Silverlight to implement clever multithreaded processing to track game-state and/or AI.
Hope that helps!Todd
Harvey
34 points
15 Posts
05-03-2007 11:18 PM |
Hi Guys,
On the subject of threading, I am trying to create a code driven animation using the System.Threading.Timer class. The problem is Timer callbacks run from another thread, so when I try to move and element I am getting "Invalid Cross-Thread access".
Is there a way to create a thread safe heartbeat?
Here is some sample code to replicate the issue
------- XAML-----------
<Canvas x:Name="parentCanvas" xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Loaded="Page_Loaded" x:Class="SilverlightProject1.Page;assembly=ClientBin/SilverlightProject1.dll" Width="640" Height="480" Background="White" > <Ellipse Canvas.Top="100" Canvas.Left="100" Fill="Black" Width="10" Height="10" x:Name="elpBall"></Ellipse></Canvas>
-----------------------------
------------------- Code------------------
using System;using System.Windows;using System.Windows.Controls;using System.Windows.Documents;using System.Windows.Ink;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Shapes;using System.Threading;namespace SilverlightProject1{ public class Page : Canvas { Ellipse elpBall; private Timer timer; public void Page_Loaded(object o, EventArgs e) { elpBall = this.FindName("elpBall") as Ellipse; timer = new Timer(Move, null, 1, -1); } private void Move(Object state) { this.elpBall.SetValue(Canvas.LeftProperty, 5); } }}
-------------------------------------
Cheers,
Javier
05-04-2007 12:17 PM |
More functionality to allow this is planned and should be there in releases before RTM, but I believe I can give you an idea of code soemthing to make this work before some more functionality is included.
In this alpha, try creating a timeline and check the time elapsed each time the callback occurs and do your work there.
For the final released product, we hope to deliver a more complete and easier way to do this.
Todd Reifsteck, Microsoft
gstasa
12 points
6 Posts
05-04-2007 5:31 PM |
Another option could be to use the System.Windows.Browser.HtmlTimer in System.Silverlight.dll.
HtmlTimer is not a high resolution timer (and you would get the warning below at compile time), but it might just do for what you need.
'System.Windows.Browser.HtmlTimer' is obsolete: 'This is not a high resolution timer and is not suitable for short-interval animations. A new timer type will be available in a future release.
Jerod Mo...
7 Posts
05-22-2007 5:37 PM |
Hi,
the HTML Timer won't work. To update the UI thread (or use timers in general) do the following:
1) Add an empty timeline to your silverlight alpha project
2) in the page load event handler, give the timeline a 1 second duration (or whatever granularity you desire).Also handle the completed event.
3) In the completed event do whatever you want then begin the timer again.
EXAMPLE
=========================
void Page_Load(object o, EventArgs args){
}
{
txtCount.Text = i.ToString();
i++;
myTimer.Begin();
You can optionaly call begin BEFORE doing stuff. Investigate Critical Sections first.
Mark Rid...
Contributor
2357 points
273 Posts
05-22-2007 6:11 PM |
There isn't a way to sync an operation with the UI thread currently in 1.1 Alpha and Silverlight is not thread safe so we don't allow users to modify on the non UI thread.Using the HtmlTimer is a good alternative or use the animation/storyboard approach. -markProgram ManagerMicrosoftThis post is provided "as-is"
05-22-2007 6:21 PM |
FYI,
this is NOT an accurate approach but just an example of periodically updating the UI thread. To get an accurate timer you should use the ACTUAL System.Threading.Timer class to change values and only use timelines to update the UI with newer values. For example:
xlj1000
26 points
13 Posts
06-11-2007 4:41 PM |
What about the case in calling web service aynschrounously? Is it safe to modify UI in the callback?
Thanks
06-25-2007 12:13 AM |
It still wont work. you'll have to use the same strategy.
luisabreu
Participant
1676 points
612 Posts
06-25-2007 5:25 AM |
xlj1000: What about the case in calling web service aynschrounously? Is it safe to modify UI in the callback?
hello.
according to my tests, it is (ie, there's already support for making the callback call on the correct thread but it simply isn't public yet).
hammadmirza
324 points
107 Posts
01-18-2008 2:43 AM |
Hi, I am doing some time consuming work 4-5 seconds, in a Thread but i also have a Storyboard in Page.xaml.cs (Loading/Working Animation), it starts when i start the Thread now when the thread completes....it sends an EventHandler(object,e); and in the Handler i am trying to stop the Storyboard....i.e. (Load/Work is complete) but i get Invalid Cross thread access so tell me what should i do? - Please!
Nullable
04-05-2008 11:58 PM |
Hey, I feel your pain... I've been there and have JUST gotten over it (http://www.singingeels.com/Blogs/Nullable/2008/04/05/Silverlight_2_Beta_1__Online_Game_and_the_Pain_it_Caused.aspx).
I'll be posting an article soon that will show how to do what I mention in that post. Sorry I don't have a clear answer right now, but I need to get to bed.
WilcoB
672 points
117 Posts
04-07-2008 3:48 PM |
When this thread started, support for threading (specifically handling UI updates from different threads) was poor. There was no first-class mechanism such as "Control.Invoke". You had to work around this limitation by using other types such as a HTML timer or Silverlight storyboards, which both executed (queued) payloads on the UI thread.
Things have changed in Silverlight 2 beta 1. All ScriptObjects and DependencyObjects have a Dispatcher property of type Dispatcher. (This property is marked with EditorBrowsable(Advanced) though, which means that unless you have configured VS to show advanced members, you won't see this property. Could it be that you missed this property because of that, Timothy?) The dispatcher lets you execute a payload on the UI thread, and it is exactly what it was designed for (unlike the HTML timer or Silverlight storyboard). In other words, you should be able to update your UI from a different thread like this:
[code=C#]new Thread(()=> { mySilverlightTextBlock.Dispatcher.BeginInvoke(()=> mySilverlightTextBlock.Text = "Updated from a non-UI thread.");}).Start();Or a slightly less syntactically exotic version:
[code=C#]Thread myThread = new Thread(new ThreadStart(StartThread));myThread.Start();void StartThread() { mySilverlightTextBlock.Dispatcher.BeginInvoke(UpdateText);}void UpdateText() { mySilverlightTextBlock.Text = "Updated from a non-UI thread.";}
In addition to the dispatcher, don't forget there's also the BackgroundWorker. It makes sense to use this type when you have some work you want to do on a background thread, but update the UI as this work progresses or completes.
04-07-2008 5:25 PM |
That is absolutely beautiful (the Dispatcher.BeginInvoke)! I think there's going to be an incredible amount of "catching up" that the development community is going to have to get used to with the new names / ways of doing things in Silverlight.
Speaking of which... is there a way (I realize I'm hijacking this thread, but... I'll continue anyway).. is there a way to set an "X,Y" location to an element in code (a clean way)?
I'll give the scenario:
There's a Canvas control that has dynamically loaded ... rectangles... how do I set the r.X and r.Y? I'm currently using the "margin" property to cheat... I realize I should probably be doing some funky "SetValue" thing that taps into the Canvas, etc... but I'm hoping for a clean solution.
Thanks,
04-07-2008 6:57 PM |
You'll have to use "the funky" SetValue methods if you're using C#:
[code=C#]myCanvas.SetValue(Canvas.LeftProperty, value);
Not sure what your scenario is exactly, but using a different container control (such as StackPanel) might be more appropriate. It's probably best to start a new thread on this though.