题外话
首先感谢一直关注我博客的博友们!使我有动力一直写下去。通过几个月对Windows Phone7的学习后,对它又有了更深入的学习和了解,所以我又开了一个新章节,来把我学到的东西分享出来。也希望大家继续支持我,一起进步。
Reactive Extension for .Net framework
.Net反应性框架,在之前的.net框架中就已经有了,没想到也被应用到Windows phone7中来了。
程序员为指定异步操作指定回调,或事件处理程序的时候使用反应性编程。在异步操作完成或者事件触发的时候,就会调用方法并作为对该事件的反应。在这个模型中,数据流、异步请求、事件都可以做为可观察序列,并且接收异步消息,并通过LINQ来合成这些序列。
不过在Phone7中,这个框架只有一部分有用,主要用在:filtering events、composing multiple asynchronous web service requests、emulating data streams.
对于目前来说,在模拟器上没有办法测试Accelerometer和Location的API,就是因为得不到数据。现在可以利用这个框架来实现数据模拟了。
模拟Accelerometer数据:
Thread thread = new Thread(StartAccelerometerEmulation);
thread.Start();
am = new Accelerometer();
var aro &#61; Observable.FromEvent<AccelerometerReadingEventArgs>(
eh &#61;> am.ReadingChanged &#43;&#61; eh,
eh &#61;> am.ReadingChanged -&#61; eh);
try
{
am.Start();
}
catch (AccelerometerFailedException ae)
{
}
void InvokeAccelerometerReadingChanged(Vector3 data)
{
Deployment.Current.Dispatcher.BeginInvoke(() &#61;> AccelerometerReadingChanged(data));
}
void AccelerometerReadingChanged(Vector3 data)
{
this.textBlock1.Text &#61; "x: " &#43; data.X.ToString("0.00");
this.textBlock2.Text &#61; " y: " &#43; data.Y.ToString("0.00");
this.textBlock3.Text &#61; " z: " &#43; data.Z.ToString("0.00");
}
private void StartAccelerometerEmulation()
{
var emulationDataAsObservable &#61; EmulateAccelerometerReading().ToObservable();
emulationDataAsObservable.Subscribe(args &#61;> InvokeAccelerometerReadingChanged(args));
}
static IEnumerable<Vector3> EmulateAccelerometerReading()
{
Random random &#61; new Random();
for (double theta &#61; 0; ; theta &#43;&#61; .1)
{
Vector3 reading &#61; new Vector3((float)Math.Sin(theta), (float)Math.Cos(theta * 1.1), (float)Math.Sin(theta * .7));
reading.Normalize();
if (random.NextDouble() > .95)
{
reading &#61; new Vector3((float)(random.NextDouble() * 3.0 - 1.5),
(float)(random.NextDouble() * 3.0 - 1.5),
(float)(random.NextDouble() * 3.0 - 1.5));
}
yield return reading;
Thread.Sleep(200);
}
}
模拟Location数据&#xff1a;
Thread t &#61; new Thread(StartLocationEmulation);
t.Start();
watcher &#61; new GeoCoordinateWatcher(GeoPositionAccuracy.Default);
watcher.MovementThreshold &#61; 35;
var gcwo &#61; Observable.FromEvent<GeoPositionChangedEventArgs<GeoCoordinate>>(
eh &#61;>watcher.PositionChanged &#43;&#61;eh,
eh &#61;>watcher.PositionChanged -&#61;eh);
watcher.Start();
private void StartLocationEmulation()
{
var position &#61; EmulatePositionChangedEvents().ToObservable();
position.Subscribe(ev &#61;> wait_PositionChanged(null, ev));
}
static IEnumerable<GeoPositionChangedEventArgs<GeoCoordinate>> EmulatePositionChangedEvents()
{
Random random &#61; new Random();
while (true)
{
double latitude &#61; (random.NextDouble() * 180.0) - 90.0; // latitude is between -90 and 90
double longitude &#61; (random.NextDouble() * 360.0) - 180.0; // longitude is between -180 and 180
yield return new GeoPositionChangedEventArgs<GeoCoordinate>(
new GeoPosition<GeoCoordinate>(DateTimeOffset.Now, new GeoCoordinate(latitude, longitude)));
Thread.Sleep(random.Next(2000));
}
}
private void wait_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
Deployment.Current.Dispatcher.BeginInvoke(()&#61;>MyPositionChanged(e));
}
private void MyPositionChanged(GeoPositionChangedEventArgs<GeoCoordinate> e)
{
this.textBlock1.Text &#61; "Time: " &#43; e.Position.Timestamp. ToString("yyyy-MM-dd hh:mm:ss");
this.textBlock2.Text &#61; "Latitude: " &#43; e.Position.Location.Latitude.ToString("0.00");
this.textBlock3.Text &#61; "Longitude: " &#43; e.Position.Location.Longitude.ToString("0.00");
}