I am writing a small UWP app to read data from a BLE (Bluetooth Low Energy) sensor. The only reason I am using UWP is because it is the only plattform that supports BLE in Windows. The functionality of the app is very simple, I just connect to the device, read data from it and log it to a csv. The Bluetooth connectivity part is already solved and only circunstantial to the question.
The way I tried to accomplish the csv logging:
- A button in the UI connects to the
void async Pick_FolderAsync
Event Handler - This method picks a folder through a
FolderPicker
and creates a file inside it - The
StorageFolder
andStorageFile
are stored as properties in my MainPage class and are added to theFutureAccessList
Now to the problem. The Bluetooth management is done in a BluetoothManager class, which connects to the device and defines an Event Handler for the characteristic change (BLE terminology for sensor data coming through):
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);
}
Which in turn triggers an Event (OnUpdateCharacteristic), to be caught by a method of the MainPage class:
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");
}
It is in this point where I get a System.IO.FileLoadException, as the file does not belong to the calling Thread.
If I were to continue on my own, I would try to get a Dispatcher for the Thread where the StorageFile is created and then invoke it to perform the write operation, but this seems to require the WindowsBase.dll assembly, which is very likely overkill for this.
As you can probably tell, I am pretty new in C#, so there is probably some easy way around this. Please do not hesitate to ask for more information.
EDIT The Stack Trace of the exception:
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