Я пишу небольшое приложение UWP для чтения данных с датчика BLE (Bluetooth Low Energy). Единственная причина, по которой я использую UWP, заключается в том, что это единственная платформа, которая поддерживает BLE в Windows. Функциональность приложения очень проста, я просто подключаюсь к устройству, читаю данные с него и записываю его в csv. Часть с подключением Bluetooth уже решена и только косвенно связана с вопросом.
Способ, которым я пытался выполнить ведение журнала csv:
- Кнопка в пользовательском интерфейсе подключается к
void async Pick_FolderAsync
Обработчик событий - Этот метод выбирает папку через
FolderPicker
и создает внутри нее файл StorageFolder
и StorageFile
сохраняются как свойства в моем классе MainPage и добавляются вFutureAccessList
Теперь к проблеме. Управление Bluetooth осуществляется в классе BluetoothManager, который подключается к устройству и определяет обработчик событий для изменения характеристики (терминология BLE для поступающих данных датчика):
public event EventHandler<UInt64> UpdateCharacteristic;
public delegate void UpdateCharacteristicEventHandler(object sender, UInt64 e);
protected virtual void OnUpdateCharacteristic(UInt64 e) => UpdateCharacteristic?.Invoke(this, e);
private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
var reader = DataReader.FromBuffer(args.CharacteristicValue);
UInt64 res = reader.ReadUInt64();
OnUpdateLog("Characteristic " + sender.Uuid + " changed. New value: " + res);
}
, который, в свою очередь, вызывает событие (OnUpdateCharacteristic), перехватывается методом класса MainPage:
BluetoothManager.UpdateCharacteristic += Update_CharacteristicAsync;
private async void Update_CharacteristicAsync(object sender, ulong e) => await Update_CharAsync(e);
private async Task Update_CharAsync(ulong e)
{
await FileIO.AppendTextAsync(LogFile, DateTime.Now.ToLongDateString() + ";" + e + "\n");
}
Именно в этой точке я получаю исключение System.IO.FileLoadException, поскольку файл не принадлежит вызывающему потоку.
Если бы я продолжил самостоятельно, я бы попытался получить Dispatcher для потока, в котором создается StorageFile, и затем вызвать его для выполнения операции записи, но, похоже, для этого требуется сборка WindowsBase.dll,что, скорее всего, излишне для этого.
Как вы, вероятно, можете сказать, я довольно новичок в C #, так что, возможно, есть несколько простых способов обойти это. Пожалуйста, не стесняйтесь спрашивать дополнительную информацию.
РЕДАКТИРОВАТЬ Трассировка стека исключения:
System.IO.FileLoadException
HResult=0x80070020
Message=Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird.
Source=System.Private.CoreLib
StackTrace:
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Device_Reader.MainPage.<Update_CharAsync>d__26.MoveNext() in D:\...\MainPage.xaml.cs:line 107
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Device_Reader.MainPage.<Update_CharacteristicAsync>d__25.MoveNext() in D:\...\MainPage.xaml.cs:line 103