I viewed this blog http://blogs.msdn.com/b/netmfteam/archive/2008/03/04/using-the-dispatcher.aspx
Please provide an example of sending text from one thread to a gadgeteer display (DisplayN7). Is this possible?
Almost: thank you Andre.m:
Please advise re a Gadgeteer module like DisplayN7 and:
displayN7.SimpleGraphics.DisplayText(“Some message”, Resources.GetFont(Resources.FontResources.NinaB), GT.Color.Yellow, 100, 400);
reference the blog:
public Object Invoke (
TimeSpan timeout,
Delegate method,
Object[] args
)
Parameters
timeout
The maximum amount of time the program will wait for the operation to finish.
method
A delegate to a method that takes multiple arguments, which is pushed onto the Dispatcher object’s event queue.
args
[ParamArrayAttribute] An object to be passed as an argument to the specified method. This can be a null reference if no arguments are needed.
Return Value
The return value from the invoked delegate, or a null reference if the delegate has no return value.
Re .NET micro framework 4.3 on VS 2012
The following code has been used in non-NETMF projects. I am seeking help to write the equivalent code in .NET micro framework 4.3
I would be grateful for examples based on the same functions. My old code (non-NETMF) is as follows:
namespace WFserver
{
public delegate void SetTextCallback(string str);
public delegate int GetLeftSpeedCallback();
...
public Form1()
{
...
Thread t4 = new Thread(new ThreadStart(CommandWorker));
...
public void SetText(string str)
{
if (this.textBoxData.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { str });
}
else
{
this.textBoxData.Text = str;
}
}
private int GetLeftSpeed()
{
if (this.tbLeftSpeed.InvokeRequired)
{
GetLeftSpeedCallback d = new GetLeftSpeedCallback(GetLeftSpeed);
object returned = this.Invoke(d, new object[] {});
return (int)returned;
}
else
{
return iLeftSpeed;
}
}
public void CommandWorker()
{
...
while (bContinue)
{
iLeftSpeed = this.GetLeftSpeed();
...
sb.Append(Encoding.UTF8.GetChars(bBuffer), 0, len);
sb.Append(" ");
this.SetText(sb.ToString());
...
My current attempt is not much like the above:
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
namespace MFText
{
public delegate void SetTextCallback(string str);
public class Program : Microsoft.SPOT.Application
{
int i = 0;
Text text;
Dispatcher dispatcher;
public static void Main()
{
Program myApplication = new Program();
Window mainWindow = myApplication.CreateWindow();
// Create the object that configures the GPIO pins to buttons.
GPIOButtonInputProvider inputProvider = new GPIOButtonInputProvider(null);
// Start the application
myApplication.Run(mainWindow);
}
private Window mainWindow;
public Window CreateWindow()
{
// Create a window object and set its size to the
// size of the display.
mainWindow = new Window();
mainWindow.Height = SystemMetrics.ScreenHeight;
mainWindow.Width = SystemMetrics.ScreenWidth;
//mainWindow.Foreground = new SolidColorBrush(Colors.Black);
mainWindow.Background = new LinearGradientBrush(Colors.Black, Colors.Blue, 0, 0, SystemMetrics.ScreenWidth, SystemMetrics.ScreenHeight);
// Create a single text control.
text = new Text();
text.ForeColor = Microsoft.SPOT.Presentation.Media.Colors.Yellow;
text.Font = Resources.GetFont(Resources.FontResources.NinaB);
text.TextContent = Resources.GetString(Resources.StringResources.String1);
text.HorizontalAlignment = Microsoft.SPOT.Presentation.HorizontalAlignment.Left;
text.VerticalAlignment = Microsoft.SPOT.Presentation.VerticalAlignment.Top;
// Add the text control to the window.
mainWindow.Child = text;
// Connect the button handler to all of the buttons.
mainWindow.AddHandler(Buttons.ButtonUpEvent, new RoutedEventHandler(OnButtonUp), false);
// Set the window visibility to visible.
mainWindow.Visibility = Visibility.Visible;
// Attach the button focus to the window.
Buttons.Focus(mainWindow);
dispatcher = Application.Current.Dispatcher;
Thread t1 = new Thread(new ThreadStart(SetTextThread));
t1.Start();
SetText("Kevin at home sleeping");
return mainWindow;
}
public void SetText(string str)
{
if (!this.text.CheckAccess())
{
DispatcherOperationCallback d = new DispatcherOperationCallback(delegate(object o)
{
int iFixed = ++i;
Debug.Print("Dispatcher Called " + iFixed.ToString());
this.text.TextContent = str + iFixed.ToString();
return null;
} );
dispatcher.BeginInvoke(d , new object[] { str });
/*
dispatcher.BeginInvoke(
new DispatcherOperationCallback(
delegate(object o)
{
int iFixed = ++i;
Debug.Print("Dispatcher Called " + iFixed.ToString());
this.text.TextContent = str + iFixed.ToString();
return null;
}
), null
);
*/
}
else
{
text.TextContent = str;
}
}
public void SetTextThread()
{
while (true)
{
SetText("Kevin coding C#");
Thread.Sleep(1000);
}
}
private void OnButtonUp(object sender, RoutedEventArgs evt)
{
ButtonEventArgs e = (ButtonEventArgs)evt;
// Print the button code to the Visual Studio output window.
Debug.Print(e.Button.ToString());
}
}
}
The function I wish to call from a new thread is:
static void N7_Display(string str, int blankrows, int colstart)
{
StringBuilder sbRow = new StringBuilder();
Int32 wordNum = 0;
Int32 strLength = str.Length;
char[] separatorChar = new char[1] { ' ' };
string[] words = str.Split(separatorChar);
Int32 wordsLen = words.Length;
string strRow;
char[] arrayRow = new char[columns];
try
{
row = row + blankrows;
while (row <= rows - 1)
{
if (indent == 0)
column = indent = colstart;
else
column = colstart = indent;
while (wordNum <= wordsLen)
{
if (wordNum < wordsLen)
column = column + words[wordNum].Length + 1;
if (column > columns - indent || wordNum == wordsLen)
{
strRow = sbRow.ToString();
arrayRow = strRow.ToCharArray();
Array.Copy(arrayRow, 0, screenStore, (row * columns), arrayRow.Length);
Screen.DrawTextInRect(strRow, 5 + (indent * 5), 5 + (row * 20), 790, 470, dtFlags, Colors.Yellow, myFont);
Screen.Flush();
sbRow.Clear();
if (++row > rows - 1)
{
row = 0;
//Thread.Sleep(3000);
Screen.Clear();
Screen.Flush();
}
break;
}
else
{
if (column <= columns - indent)
{
sbRow.Append(words[wordNum] + " ");
if (wordNum < wordsLen)
wordNum++;
}
}
}
if (wordNum == wordsLen)
{
wordNum = 0;
break;
}
}
}
catch (Exception ex)
{
Debug.Print("General Exception: " + ex.Message);
}
}
I find DispatcherOperationCallback(object (object) target) the most difficult to understand.
Many thanks for any advice,
Kevin.
In the first test project I setup a main thread, on which I created the window and three other threads (one for data, one for commands and the third for UART). The function above N7_Display(string str, int blankrows, int colstart) works on any of the four threads without using the Dispatcher but not with the Dispatcher!
The second project with one main thread and one additional thread: the above function worked without the Dispatcher and with andre.m’s code above added it worked ok also.
A puzzle…
@ KG1 - Did you manage to solve this. I am looking for better Dispatcher examples…?