Band SDK似乎不能在任何地方工作,但代码隐藏

时间:2016-01-09 23:12:14

标签: sdk win-universal-app microsoft-band

使用MVVMLight的通用应用程序。

所以我开始想知道为什么所有的SDK示例都是从代码背后完成而不是使用一个可靠的Wrapper类。

所以我想编写一个可重用的包装类。没运气。即使尝试将该包装器添加到ViewModel,仍然没有运气。

从MainView.xaml.cs中正常工作

IBandInfo[] pairedBands = BandClientManager.Instance.GetBandsAsync().Result;
            if (pairedBands.Length > 0)
            {
                using (IBandClient bandClient = await BandClientManager.Instance.ConnectAsync(pairedBands[0]))
                {

                }
            }

当我转移到任何类型的OOP或View Model时,ConnectAsync将永远不会返回或抛出异常。我试过这20种不同的方式,SDK坏了吗?怎么了?没有消息,没有投掷,只是永远不会回来。

如果我抛弃Code,那么它可以正常工作并在1/2秒内返回客户端。

到目前为止,我已经花了5-6个小时。我想为SDK创建一个可靠的包装类,这样我就可以调用Model的简单调用,并执行StartListener(MicrosoftBandSensor sensorToActivate)之类的操作。

有什么建议吗?

- 菲尔的评论

我正在尝试为客户端和bandinfo创建支持变量,这些变量将保存在VM使用的类中。我把我的课写成了IDisposable,所以当我完成我的包装时,我可以处理这两个。说实话,我可能会用这个错误。

 MicrosoftBand.MicrosoftBandClient = BandClientManager.Instance.ConnectAsync(pairedBands[0]).Result;

我想要调用它作为同步调用,因为我想在构造函数中调用bandinfo和client然后保持两者直到类被销毁并在需要时调用变量。

我的VM有:

public BandInformation MicrosoftBand
        {
            get { return _microsoftBand; }
            set { Set(() => MicrosoftBand, ref _microsoftBand, value); }
        }

如果他们没有在构造函数中传递bandclient,我会使用:

 private async Task InitBand(IBandInfo bandInfo)
        {

            if (bandInfo == null)
            {
                var allBands = await BandClientManager.Instance.GetBandsAsync();
                if (allBands.Length > 0)
                {
                    bandInfo = allBands[0];
                }
            }
            var bandClient = await BandClientManager.Instance.ConnectAsync(bandInfo);
            MicrosoftBandInfo = bandInfo;
            MicrosoftBandClient = bandClient;

            if (MicrosoftBandClient == null)
            {
                AddErrorMessage("This sample app requires a Microsoft Band paired to your device.Also make sure that you have the latest firmware installed on your Band, as provided by the latest Microsoft Health app.");
            }

        }

使用BandInfo似乎很好。我找回了一个看起来像工作对象的坚固对于客户我得到了"线程退出"没有别的。

注意:我曾经尝试过一次性抓住一次性版本,也没有任何例外。

我认为你可以这样做,就像你自己处理处理的任何其他IDisposable一样。

我每次都可以重新实现BandClient,只是想到我需要在某个时候分离事件,这意味着我必须保持对bandclient的支持。我可以保留它直到完成,并且每次都需要添加和删除事件。

2 个答案:

答案 0 :(得分:1)

您的VM构造函数中对.Result的阻塞调用很可能是导致挂起的原因。 IBandClientManager.ConnectAsync()可以隐式显示UI(Windows运行时对话框,要求用户确认她想要使用该特定蓝牙设备)。如果您在尝试显示UI时阻止了UI线程,那么您现在已陷入僵局。

调用Task.Result几乎不是一个好主意,更不用说在构造函数中这样做了,你不知道构造函数正在执行哪个线程。如果您正在使用异步API(例如Band SDK),那么您最好的选择是保持该交互异步。而是推迟调用ConnectAsync(),直到您确实需要,并从VM中的异步方法执行此操作。 (无论如何,推迟连接都是一个好主意,因为您希望最小化连接到频段的时间以延长电池寿命。)然后尽早调用Dispose()以关闭蓝牙连接。

答案 1 :(得分:0)

所以我去看了一堆例子。最后,我登陆了MSDN网站上的GravityHeroUAP演示。 https://msdn.microsoft.com/en-us/magazine/mt573717.aspx?f=255&MSPPError=-2147217396

我查看了他的代码和来源:https://github.com/kevinash/GravityHeroUWP 他本质上是在做我想做的事。

但是,我注意到了一些奇怪的事情。在他的视图模型中,一切都是静态的!

  public static IBandInfo SelectedBand
        {
            get { return BandModel._selectedBand; }
            set { BandModel._selectedBand = value; }
        }

        private static IBandClient _bandClient;
        public static IBandClient BandClient
        {
            get { return _bandClient; }
            set
            {
                _bandClient = value;
            }
        }

我最终复制了这个模式(虽然在这个过程中不得不扔掉我最喜欢的MVVM lib,但我相信我能把它拿回来)。

我在VM中的常见模式:

  public string ExceptionOnStart {
            get { return _exceptionOnStart; }
            set { Set(() => ExceptionOnStart, ref _exceptionOnStart, value); }
       }

现在似乎正在运作!

那和我的数据方式太快了

await Windows.Storage.FileIO.AppendLinesAsync(dataFile, new List<string> { toWrite });

感谢Phil的帮助,它让我朝着正确的方向前进! 非常非常感谢你。花了这么多时间。标记