- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 C# 异步编程的新手,我遇到了一些异步方法的问题。这些方法与外部蓝牙运动传感器通信。问题在于,在极少数情况下,相同的方法会等待从未运行过的任务。
情况如下图。任务 MBientLab.MetaWear.Impl.MetaWearBoard.createRouteAsync() 等待计划任务完成。因此,该任务必须从 MBientLab.MetaWear.Impl.MetaWearBoard.createRouteAsync() 任务中启动,该任务是所用 API 的一部分。
因此,正如我们所见,突出显示的行是一个已安排并等待运行的任务,但无论我等待多长时间,它都会保持该状态。它永远不会进入事件状态。其他任务正在等待突出显示的任务完成,所以一切都卡住了。
这可能是死锁,还是任务在等待永远无法完成的事情?我有点困惑,我不知道如何解决这个问题。
编辑:我提取了导致问题的代码。它需要来自 using 语句、Windows SDK 和传感器的 block 才能工作。所以你可能无法运行它,但也许有一些明显的错误。
// Nuggets
using MbientLab.MetaWear;
using MbientLab.MetaWear.Core;
using MbientLab.MetaWear.Data;
using MbientLab.MetaWear.Sensor;
using MbientLab.MetaWear.Win10;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
namespace MBientLabSensor
{
public class MotionSensor
{
public List<double> GetX { get; } = new List<double>();
public List<double> GetY { get; } = new List<double>();
public List<double> GetZ { get; } = new List<double>();
IMetaWearBoard _metawearDevice = null;
// List of Bluetooth devices found after scanning
private List<BluetoothLEDevice> DeviceList = new List<BluetoothLEDevice>();
public async Task Connect(string MAC, int retries = 1)
{
if (_metawearDevice != null)
{
await StopAndDisconnectMotionSensor();
}
await ConnectToSensor(MAC.Trim(), retries);
}
public async Task StopAndDisconnectMotionSensor()
{
StopAccelerometer(_metawearDevice);
await Disconnect(_metawearDevice);
}
public void StopAccelerometer(IMetaWearBoard _metawearDevice)
{
if (_metawearDevice == null)
{
throw new ArgumentNullException("The provided device is null!");
}
var acc = _metawearDevice.GetModule<IAccelerometer>();
// Put accelerometer back into standby mode
acc.Stop();
// Stop accelerationi data
acc.Acceleration.Stop();
}
public async virtual Task Disconnect(IMetaWearBoard _metawearDevice)
{
if (_metawearDevice == null)
{
throw new ArgumentNullException("The MetaWear device instance is null!");
}
_metawearDevice.TearDown();
// Have the board terminate the BLE connection
await _metawearDevice.GetModule<IDebug>().DisconnectAsync();
}
public async Task ConnectToSensor(string MAC, int retries = 3)
{
BluetoothLEDevice device = DeviceList.Find(x => ConvertToMAC(x.BluetoothAddress).Trim() == MAC.Trim());
await AttemptConnect(device, retries);
}
private async Task AttemptConnect(BluetoothLEDevice BLEDevice, int retries)
{
_metawearDevice = await ConnectToDevice(BLEDevice, retries);
if (_metawearDevice != null)
{
Task task = Task.Run(async () => await Setup(_metawearDevice));
SetAccSamplingRate(_metawearDevice, 100f, 16f);
StartAcc(_metawearDevice);
}
}
public async Task Setup(IMetaWearBoard device, float connInterval = 7.5f)
{
if (device == null)
{
throw new ArgumentNullException("The provided device is null!");
}
// Set the connection interval
await SetBLEConnectionInterval(device, connInterval);
var acc = device.GetModule<IAccelerometer>();
// Use data route framework to tell the MetaMotion to stream accelerometer data to the host device
await acc.Acceleration.AddRouteAsync(source => source.Stream(data =>
{
// Clear buffers if there is too much data inside them
if (GetX.Count > 1000)
{
ClearSensorData();
}
// Buffer received data
GetX.Add(data.Value<Acceleration>().X);
GetY.Add(data.Value<Acceleration>().Y);
GetZ.Add(data.Value<Acceleration>().Z);
}));
}
public void ClearSensorData()
{
GetX.Clear();
GetY.Clear();
GetZ.Clear();
}
private async Task SetBLEConnectionInterval(IMetaWearBoard device, float maxConnInterval = 7.5f)
{
if (device == null)
{
throw new ArgumentNullException("The provided device is null!");
}
// Adjust the max connection interval
device.GetModule<ISettings>()?.EditBleConnParams(maxConnInterval: maxConnInterval);
await Task.Delay(1500);
}
public void SetAccSamplingRate(IMetaWearBoard device, float samplingRate = 100f, float dataRange = 16f)
{
if (device == null)
{
throw new ArgumentNullException("The provided device is null!");
}
var acc = device.GetModule<IAccelerometer>();
// Set the data rate and data to the specified values or closest valid values
acc.Configure(odr: samplingRate, range: dataRange);
}
public void StartAcc(IMetaWearBoard device)
{
if (device == null)
{
throw new ArgumentNullException("The provided device is null!");
}
var acc = device.GetModule<MbientLab.MetaWear.Sensor.IAccelerometer>();
// Start the acceleration data
acc.Acceleration.Start();
// Put accelerometer in active mode
acc.Start();
}
public async virtual Task<IMetaWearBoard> ConnectToDevice(BluetoothLEDevice device, int retries = 1)
{
_metawearDevice = Application.GetMetaWearBoard(device);
if (_metawearDevice == null)
{
throw new ArgumentNullException("The MetaWear device is null!");
}
// How long the API should wait (in milliseconds) before a required response is received
_metawearDevice.TimeForResponse = 5000;
int x = retries;
do
{
try
{
await _metawearDevice.InitializeAsync();
retries = -1;
}
catch (Exception e)
{
retries--;
}
} while (retries > 0);
if (retries == 0)
{
return null;
}
else
{
return _metawearDevice;
}
}
private string ConvertToMAC(ulong value)
{
string hexString = value.ToString("X");
// Pad the hex string with zeros on the left until 12 nibbles (6 bytes) are present
hexString = hexString.PadLeft(12, '0');
return hexString.Insert(2, ":").Insert(5, ":").Insert(8, ":").Insert(11, ":").Insert(14, ":");
}
}
}
我用
运行它Task.Run(async () => await Connect(MAC, 3));
最佳答案
Task.Run()
将您的代码包装到 Task
中。 Task 正在执行,但您需要捕获 Task 执行的结果。所以你需要这样做:
var task = Task.Run(async () => await Connect(MAC, 3));
await task;
但是这样做是没有意义的。如果您想等待异步操作,只需执行以下操作:
await Connect(Mac, 3)
关于c# - 任务已安排并等待运行但从未执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58131068/
背景 我最近在 merge 期间遇到了一个意外未 merge 的文档文件的问题。 无论出于何种原因,我搞砸了 merge 并有效地删除了文件(和其他几个文件),因为我忘记了它们的存在。 现在我想查看我
我在我的网站上使用旧的 mysql 版本和 php 版本 4。 我的表结构: | orders_status_history_id | orders_id | orders_status_id |
我是一名优秀的程序员,十分优秀!