My situation: I'm logging into my app. After the login, chats will be loaded (it's a chat app). I'm trying to use DataWriter.StoreAsync
, but it will always throw this exception:
A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)
I've read a lot about async code in the past days and I'm struggling a lot with this exception. What I (believe to) know:
await
every time I'm running async code, otherwise my code won't wait for the return and throw exceptionsasync void
because it won't return (only exception: events)DataWriter
after I used it to make sure that there won't be multiple threads using the same DataWriter
Unfortunately my code still throws the exception stated above. Maybe I forgot something or understood something about async
wrong.
Since I'm working with server, it's not possible for me to provide a sample project. Sorry! Wall of code incoming now, sorry about that but my mistake could be anywhere in this code. The code is sorted by when it's executed from top to bottom:
Instance of LoginCommand
in MainPageViewModel
:
LoginCommand = new DelegateCommand(Login);
My Login
method:
private async void Login()
{
_evaLogger.Info("Trying to log in (online)...");
await LoginOnline();
_evaLogger.Info("Logged in (online)!!!");
}
The method is async void
instead of async Task
because DelegateCommand
doesn't allow a Task
and DelegateCommand.FromAsyncHandler
is obsolete. But besides that, I've tried DelegateCommand.FromAsyncHandler
and it didn't solve the issue.
LoginOnline()
:
private async Task LoginOnline()
{
// ... Other code ...
await _websocketManager.connect(_accountInformation.GetToken(), _eventAggregator, _evaLogger, _dependencyService);
}
The _websocketManager.connect()
method for my UWP implementation is this:
public async Task connect(string token, IEventAggregator eventAggregator, EvaLogger evaLogger, IDependencyService dependencyService)
{
try
{
messageWebsocket.SetRequestHeader("iPlanetDirectoryPro", token);
DependencyService = dependencyService;
_eventAggregator = eventAggregator;
_evaLogger = evaLogger;
_localDataManager = new SqliteLocalDataManager(_evaLogger, _eventAggregator, dependencyService);
messageWebsocket.Control.MessageType = SocketMessageType.Utf8;
messageWebsocket.MessageReceived += OnMessageReceived;
messageWebsocket.Closed += OnClosed;
messageWebsocket.ServerCustomValidationRequested += OnOpened;
_evaLogger.Info("WebsocketManager.Connect();");
await messageWebsocket.ConnectAsync(WSURI); // This triggers the OnOpened event
}
catch (Exception e)
{
_evaLogger.Error(e.Message, e);
}
}
Then the OnOpened event is triggered, which calls the OnOpened
method. After some other code which isn't relevant for this exception and after a navigation which works fine, the async void OnNavigatedTo
method is called. According to [this SO question], using async void here is fine:1
public async void OnNavigatedTo(NavigationParameters parameters)
{
await LoadDataTaskAsync();
}
LoadDataTaskAsync
method:
private async Task LoadDataTaskAsync()
{
// ... Other code ...
_evaLogger.Info("LoadDataTaskAsync()");
await _remoteDataManager.requestChats();
}
public async Task requestChats()
{
await _websocketManager.requestChats(); // Gets the requestChats implementation for the current platform (in my case UWP)
}
requestChats():
public async Task requestChats()
{
using (DataWriter dataWriter = new DataWriter(messageWebsocket.OutputStream))
{
_evaLogger.Info("dataWriter initialized requestChats.");
dataWriter.WriteString(WebsocketRequestFactory.Create(SocketEventsEnm.GET_CHATS));
await SendData(dataWriter, "requestChats");
}
_evaLogger.Info("dataWriter disposed requestChats.");
}
And finally, SendData()
:
private async Task SendData(DataWriter dataWriter, string method)
{
try
{
_evaLogger.Info("Trying to send data... " + method);
await dataWriter.StoreAsync(); // Exception is thrown here!!!
_evaLogger.Info("Data was sent." + method);
}
catch (Exception e)
{
_evaLogger.Error(e.Message, e);
}
}
This is how my logfile looks after I run the application:
14.12.2016 15:36:33 - Info: Trying to log in (online)...
14.12.2016 15:36:33 - Info: WebsocketManager.Connect();
14.12.2016 15:36:33 - Info: MessageWebSocket Opened
14.12.2016 15:36:33 - Info: LoadDataTaskAsync()
14.12.2016 15:36:33 - Info: dataWriter initialized requestChats.
14.12.2016 15:36:33 - Info: Trying to send data... requestChats
14.12.2016 15:36:33 - Error: A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)
14.12.2016 15:36:33 - Info: dataWriter disposed requestChats.
14.12.2016 15:36:34 - Info: Websocket Opened
14.12.2016 15:36:34 - Info: Logged in (online)!!!
The logfile looks (except for the exception) fine for me, everything is executed in the right order.
Again, sorry for the long code. But I think it could be everywhere in this code and I removed every unnecessary line of code which doesn't cause the exception for sure (this is why it might seem weird why I have so many methods).
After removing the OnOpened
event, it's working most of the times. But I'm still getting the same exception occasionally.
This is the stacktrace:
Error: A method was called at an unexpected time. (Exception from HRESULT: 0x8000000E)
at Windows.Storage.Streams.DataWriter.StoreAsync()
at One.UWP.Websockets.WebsocketManager.<SendData>d__30.MoveNext()
User contributions licensed under CC BY-SA 3.0