如何 return 地理定位而不是 IAsyncOperation<Geoposition> 或 Task<Geoposition>?
How to return Geoposition instead of IAsyncOperation<Geoposition> or Task<Geoposition>?
我在我的 javascript UWP 应用程序中创建了一个 Windows Runtime Component (C#),但我无法return 得到我想要的结果。它构建良好,但在调试时,null 被 returned,而不是 Geoposition 对象。
由于下面的函数需要在我的 javascript 应用程序中调用,看来我 can't use the async keyword, 但我可以在包装器中完成它:
public static Geoposition GetGeolocation()
{
Geolocator _geolocator = new Geolocator();
MapLocation mapInfo = null;
_geolocator.DesiredAccuracyInMeters = 5;
try
{
Geoposition currentPosition = GetGeopoisitionWrapper(_geolocator).Result;
// Geoposition currentPosition = GetGeopoisitionWrapper(_geolocator).AsAsyncOperation().GetResults();
//other stuff needing currentPosition, and another async function call
return currentPosition;
}
catch (Exception ex)
{
return null;
}
}
包装器:
private static async Task<Geoposition> GetGeopositionWrapper(Geolocator g)
{
Geoposition currentPosition = await g.GetGeopositionAsync(); // get the raw geoposition data
return currentPosition;
}
Javascript函数调用:
function getLocationForMap() {
Windows.Devices.Geolocation.Geolocator.requestAccessAsync().done(
function (accessStatus) {
switch (accessStatus) {
case Windows.Devices.Geolocation.GeolocationAccessStatus.allowed:
var result = SampleComponent.Example.getGeolocation();
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.denied:
WinJS.log && WinJS.log("Access to location is denied.", "sample", "error");
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.unspecified:
WinJS.log && WinJS.log("Unspecified error!", "sample", "error");
break;
}
},
function (err) {
WinJS.log && WinJS.log(err, "sample", "error");
});
}
我需要在 C# 中完成这部分的原因是因为 javascript API 中缺少我需要的函数调用之一(也许开发人员忘记包含它),但是存在于 C# 中。
您必须确保使用清单(Package.appxmanifest 文件)设置了 Location Capability:
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
IgnorableNamespaces="uap mp">
// You should have this
<Capabilities>
<DeviceCapability Name="location"/>
</Capabilities>
</Package>
是的,你不能使用await。但是你可以使用 promises。您必须使用 Windows 运行时数据类型才能实现 JS/C# 互操作性才能使其正常工作。听起来比实际更复杂:
像这样更改 windows 运行时组件中的 C# 代码:
public static IAsyncOperation <Geoposition> GetGeopoisitionAsync()
{
Geolocator g = new Geolocator();
return g.GetGeopositionAsync() as IAsyncOperation<Geoposition> ;
}
或者如果您想在将地理定位传递给 Javascript 之前在 C# 中访问它,如下所示:
public IAsyncOperation<Geoposition> GetPositionAsync2()
{
return Task.Run<Geoposition>(async () => {
Geolocator g = new Geolocator();
var pos = await g.GetGeopositionAsync();
// Do something with pos here..
return pos;
}).AsAsyncOperation();
可以直接从您的 JS 应用调用此方法。确保设置位置兼容性并从 JS 应用程序引用组件项目。
调用 - 基于您的示例代码 - 如下所示:
function getLocationForMap() {
Windows.Devices.Geolocation.Geolocator.requestAccessAsync().done(
function (accessStatus) {
switch (accessStatus) {
case Windows.Devices.Geolocation.GeolocationAccessStatus.allowed:
// call the WinRT Component
var rc = RuntimeComponent1.Class1;
// use promises to wait for completion
rc.getGeopoisitionAsync().then(function (res) {
// access the props of the result
var m = new Windows.UI.Popups.MessageDialog(res.coordinate.latitude);
// show latitude in message box
m.showAsync();
});
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.denied:
WinJS.log && WinJS.log("Access to location is denied.", "sample", "error");
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.unspecified:
WinJS.log && WinJS.log("Unspecified error!", "sample", "error");
break;
}
},
function (err) {
WinJS.log && WinJS.log(err, "sample", "error");
});
}
在我的机器上工作:-)
在此处查看基于您的代码的完整工作示例:https://github.com/DanielMeixner/so/tree/master/JSAppGeolocation
我在我的 javascript UWP 应用程序中创建了一个 Windows Runtime Component (C#),但我无法return 得到我想要的结果。它构建良好,但在调试时,null 被 returned,而不是 Geoposition 对象。
由于下面的函数需要在我的 javascript 应用程序中调用,看来我 can't use the async keyword, 但我可以在包装器中完成它:
public static Geoposition GetGeolocation()
{
Geolocator _geolocator = new Geolocator();
MapLocation mapInfo = null;
_geolocator.DesiredAccuracyInMeters = 5;
try
{
Geoposition currentPosition = GetGeopoisitionWrapper(_geolocator).Result;
// Geoposition currentPosition = GetGeopoisitionWrapper(_geolocator).AsAsyncOperation().GetResults();
//other stuff needing currentPosition, and another async function call
return currentPosition;
}
catch (Exception ex)
{
return null;
}
}
包装器:
private static async Task<Geoposition> GetGeopositionWrapper(Geolocator g)
{
Geoposition currentPosition = await g.GetGeopositionAsync(); // get the raw geoposition data
return currentPosition;
}
Javascript函数调用:
function getLocationForMap() {
Windows.Devices.Geolocation.Geolocator.requestAccessAsync().done(
function (accessStatus) {
switch (accessStatus) {
case Windows.Devices.Geolocation.GeolocationAccessStatus.allowed:
var result = SampleComponent.Example.getGeolocation();
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.denied:
WinJS.log && WinJS.log("Access to location is denied.", "sample", "error");
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.unspecified:
WinJS.log && WinJS.log("Unspecified error!", "sample", "error");
break;
}
},
function (err) {
WinJS.log && WinJS.log(err, "sample", "error");
});
}
我需要在 C# 中完成这部分的原因是因为 javascript API 中缺少我需要的函数调用之一(也许开发人员忘记包含它),但是存在于 C# 中。
您必须确保使用清单(Package.appxmanifest 文件)设置了 Location Capability:
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
IgnorableNamespaces="uap mp">
// You should have this
<Capabilities>
<DeviceCapability Name="location"/>
</Capabilities>
</Package>
是的,你不能使用await。但是你可以使用 promises。您必须使用 Windows 运行时数据类型才能实现 JS/C# 互操作性才能使其正常工作。听起来比实际更复杂:
像这样更改 windows 运行时组件中的 C# 代码:
public static IAsyncOperation <Geoposition> GetGeopoisitionAsync()
{
Geolocator g = new Geolocator();
return g.GetGeopositionAsync() as IAsyncOperation<Geoposition> ;
}
或者如果您想在将地理定位传递给 Javascript 之前在 C# 中访问它,如下所示:
public IAsyncOperation<Geoposition> GetPositionAsync2()
{
return Task.Run<Geoposition>(async () => {
Geolocator g = new Geolocator();
var pos = await g.GetGeopositionAsync();
// Do something with pos here..
return pos;
}).AsAsyncOperation();
可以直接从您的 JS 应用调用此方法。确保设置位置兼容性并从 JS 应用程序引用组件项目。
调用 - 基于您的示例代码 - 如下所示:
function getLocationForMap() {
Windows.Devices.Geolocation.Geolocator.requestAccessAsync().done(
function (accessStatus) {
switch (accessStatus) {
case Windows.Devices.Geolocation.GeolocationAccessStatus.allowed:
// call the WinRT Component
var rc = RuntimeComponent1.Class1;
// use promises to wait for completion
rc.getGeopoisitionAsync().then(function (res) {
// access the props of the result
var m = new Windows.UI.Popups.MessageDialog(res.coordinate.latitude);
// show latitude in message box
m.showAsync();
});
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.denied:
WinJS.log && WinJS.log("Access to location is denied.", "sample", "error");
break;
case Windows.Devices.Geolocation.GeolocationAccessStatus.unspecified:
WinJS.log && WinJS.log("Unspecified error!", "sample", "error");
break;
}
},
function (err) {
WinJS.log && WinJS.log(err, "sample", "error");
});
}
在我的机器上工作:-) 在此处查看基于您的代码的完整工作示例:https://github.com/DanielMeixner/so/tree/master/JSAppGeolocation