使用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的支持。我可以保留它直到完成,并且每次都需要添加和删除事件。
答案 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的帮助,它让我朝着正确的方向前进! 非常非常感谢你。花了这么多时间。标记