gpt4 book ai didi

.net - InvalidOperationException 执行两次处理时

转载 作者:行者123 更新时间:2023-12-03 18:12:03 30 4
gpt4 key购买 nike

我必须编写一个异步方法来与 Web 服务联系。这是我在 WebServiceHelper 类中的方法:

 public static Task<int> SignIn(string username, string password) 
{

try
{
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
service.LoginCompleted += (object sender, WebService.LoginCompletedEventArgs e) =>
{
if (e.Error != null) tcs.SetResult(-1);
else
tcs.SetResult((int)e.Result);

};
service.LoginAsync(username, password);
return tcs.Task;
}
catch (Exception ex)
{

MessageBox.Show("Error: " + ex.Message);
return null;
}

}

然后我在一个按钮点击事件中调用它,如下所示:
private async void btLogIn_Click(object sender, RoutedEventArgs e)
{
try
{
int si = await WebServiceHelper .SignIn(tbUsername.Text, tbPassword.Text);
if (si != 0) MessageBox.Show("Signed in successfully!");
else MessageBox.Show("Couldn't sign in");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

我第一次单击该按钮时效果很好,但是当我再次单击时,出现了错误:
“InvalidOperationException,试图在任务已经完成时将其转换为最终状态。”

我做了一些小搜索,在这里找到了一些东西: Tasks seem to start automatically

我知道我应该在重新开始之前做一些事情来停止这个过程,但我不知道如何以及为什么。有人可以为我解释一下吗?

最佳答案

我怀疑问题在于您没有取消注册您的事件处理程序,并且每次调用此方法时,您都会向 service.LoginCompleted 添加一个新的匿名事件处理程序。

尝试这个

public static Task<int> SignIn( string username, string password )
{
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
EventHandler<WebService.LoginCompletedEventArgs> onLoginCompleted = null;
onLoginCompleted = ( object sender, WebService.LoginCompletedEventArgs e ) =>
{
service.LoginCompleted += onLoginCompleted;
if(e.Error != null)
{
tcs.SetResult( -1 );
}
else
{
tcs.SetResult( (int)e.Result );
}
};
service.LoginCompleted += onLoginCompleted;
service.LoginAsync( username, password );
return tcs.Task;
}

或者这个
public static Task<int> SignIn( string username, string password )
{
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
EventHandler<WebService.LoginCompletedEventArgs> onLoginCompleted = ( object sender, WebService.LoginCompletedEventArgs e ) =>
{
if(e.Error != null)
{
tcs.SetResult( -1 );
}
else
{
tcs.SetResult( (int)e.Result );
}
};
service.LoginCompleted += onLoginCompleted;
tcs.Task.ContinueWith(task => service.LoginCompleted -= onLoginCompleted);
service.LoginAsync( username, password );
return tcs.Task;
}

顺便说一句,您还应该删除通用 try/catch绕过方法并返回 tcs.Task在所有情况下。

如果实际上很可能是 service.LoginAsync( username, password )可能会抛出异常,那么你应该这样做
...
try
{
service.LoginAsync( username, password );
}
catch(SomeParticularException ex)
{
tcs.SetException(ex);
}
return tcs.Task;

关于.net - InvalidOperationException 执行两次处理时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23576870/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com