Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在意外时间调用了一个方法。(HRESULT的例外:0x800000E)_C#_Asynchronous_Deadlock - Fatal编程技术网

C# 在意外时间调用了一个方法。(HRESULT的例外:0x800000E)

C# 在意外时间调用了一个方法。(HRESULT的例外:0x800000E),c#,asynchronous,deadlock,C#,Asynchronous,Deadlock,我的情况:我正在登录我的应用程序。登录后,将加载聊天记录(这是一个聊天应用程序)。我正在尝试使用DataWriter.StoreAsync,但它始终会引发以下异常: 在意外时间调用了一个方法。(HRESULT的例外情况: 0x8000000E) 在过去的几天里,我读了很多关于异步代码的书,我一直在为这个异常挣扎。我(相信)知道的: 每次运行异步代码时,我都需要使用wait,否则我的代码不会等待返回并抛出异常 我需要避免async void,因为它不会返回(唯一的例外:事件) 我需要在使用Dat

我的情况:我正在登录我的应用程序。登录后,将加载聊天记录(这是一个聊天应用程序)。我正在尝试使用
DataWriter.StoreAsync
,但它始终会引发以下异常:

在意外时间调用了一个方法。(HRESULT的例外情况: 0x8000000E)

在过去的几天里,我读了很多关于异步代码的书,我一直在为这个异常挣扎。我(相信)知道的:

  • 每次运行异步代码时,我都需要使用
    wait
    ,否则我的代码不会等待返回并抛出异常
  • 我需要避免
    async void
    ,因为它不会返回(唯一的例外:事件)
  • 我需要在使用
    DataWriter
    后处理它,以确保不会有多个线程使用同一个
    DataWriter
不幸的是,我的代码仍然抛出上述异常。也许我忘记了什么或者理解了一些关于
async
的错误

因为我使用的是服务器,所以不可能提供一个示例项目。很抱歉代码墙正在传入,对此表示抱歉,但我的错误可能在代码中的任何地方。代码按从上到下执行的时间排序:


MainPageViewModel
中的
LoginCommand
实例:

LoginCommand = new DelegateCommand(Login);
我的
登录
方法:

private async void Login()
{
    _evaLogger.Info("Trying to log in (online)...");
    await LoginOnline();
    _evaLogger.Info("Logged in (online)!!!");
}
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)
}
该方法是
async void
而不是
async Task
,因为
DelegateCommand
不允许
Task
DelegateCommand。FromAsyncHandler
已过时。但除此之外,我还尝试了
DelegateCommand.FromAsyncHandler
,但没有解决问题

LoginOnline()

我的UWP实现的
\u websocketManager.connect()
方法如下:

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);
    }
}
然后触发OnOpened事件,该事件调用
OnOpened
方法。在一些与此异常不相关的其他代码之后,以及在运行正常的导航之后,将调用
async void on navigatedto
方法。根据[这个SO问题],在这里使用async void是可以的:

LoadDataTaskAsync
方法:

private async void Login()
{
    _evaLogger.Info("Trying to log in (online)...");
    await LoginOnline();
    _evaLogger.Info("Logged in (online)!!!");
}
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():

最后,
SendData()


这是我运行应用程序后日志文件的外观:

14.12.2016 15:36:33-信息:正在尝试登录(在线)

14.12.2016 15:36:33-信息:WebsocketManager.Connect()

14.12.2016 15:36:33-信息:MessageWebSocket已打开

14.12.2016 15:36:33-信息:LoadDataTaskAsync()

14.12.2016 15:36:33-信息:dataWriter初始化请求聊天

14.12.2016 15:36:33-信息:正在尝试发送数据。。。请求聊天

14.12.2016 15:36:33-错误:在意外时间调用了方法。(HRESULT的例外:0x800000E)

14.12.2016 15:36:33-信息:dataWriter聊天室

14.12.2016 15:36:34-信息:Websocket已打开

14.12.2016 15:36:34-信息:登录(在线)

日志文件看起来(除了异常)很好,一切都按正确的顺序执行

再一次,抱歉代码太长。但我认为它可能在这段代码中无处不在,我删除了每一行不必要的代码,这些代码肯定不会导致异常(这就是为什么我有这么多方法,这可能看起来很奇怪)

编辑: 删除打开的
OnOpened
事件后,它大部分时间都在工作。但我还是偶尔遇到同样的例外

这是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()
错误:在意外时间调用了方法。(HRESULT的例外:0x800000E)
在Windows.Storage.Streams.DataWriter.StoreAsync()中
在One.UWP.Websockets.WebsocketManager.d_u30.MoveNext()中

您是否尝试过简单地移动
dataWriter.StoreAsync()到您的
requestChats()
方法中?我的意思是,它看起来像是不必要地转移到了另一个函数中。需要这样吗?@gmiley我试过了,这改变了一些东西。。。我不会再出现异常,但我的应用程序只是毫无例外地崩溃了。最初我实现了
SendData
,因为我还有许多其他方法也需要
dataWriter.StoreAsync()
方法,但如果这样可以解决问题,我可以放弃它。您可能需要对程序流进行更多的分析。您是否在开发过程中进行单元测试以测试所有代码路径?此外,当您移动该调用时,您是否将其包装在try/catch中以输出错误,或者它现在正在被吞没。您可能仍然会遇到相同的错误。我只是想看看async/Wait是否还有其他问题,您可能会遇到。@gmiley啊,我的错误,太愚蠢了。对于try/catch,它是相同的,仍然是例外。不,我没有单元测试,但不幸的是,我目前无法投入时间
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);
    }
}
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()