C# Cancellationtoken异常未执行
我需要通过单击按钮取消以下异步方法 这就是我所尝试的:C# Cancellationtoken异常未执行,c#,wpf,cancellationtokensource,cancellation-token,C#,Wpf,Cancellationtokensource,Cancellation Token,我需要通过单击按钮取消以下异步方法 这就是我所尝试的: private CancellationTokenSource cts; private async Task<bool> ValidateFtpAsync() { cts = new CancellationTokenSource(); CancellationToken token = cts.Token; try {
private CancellationTokenSource cts;
private async Task<bool> ValidateFtpAsync()
{
cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
try
{
return await Task.Run(
() =>
{
token.ThrowIfCancellationRequested();
Global_Variables.DoingStuff = true;
if (File.Exists("settings.xml"))
{
var xs = new XmlSerializer(typeof(Information));
using (var read = new FileStream("settings.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
{
token.ThrowIfCancellationRequested();
Information info = (Information)xs.Deserialize(read);
try
{
var DecryptedInfo = FileCryptoDecryptor.ReadEncryptedConfiguration("hakuna.xml.aes", Global_Variables.AppPassword);
string DecryptedFTPPass = EncryDecryptor.Decrypt(DecryptedInfo.FtpPassword, "blablabla");
token.ThrowIfCancellationRequested();
return General_Functions.isValidConnection(info.HDSynologyIP, info.FtpUsername, DecryptedFTPPass);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
return false;
}
else
{
MessageBox.Show("Missing settings file.");
return false;
}
}, token);
}
catch(OperationCanceledException)
{
MessageBox.Show("Canceled test");
return false;
}
}
private void cancelButton_Click(object sender, RoutedEventArgs e)
{
cts.Cancel();
}
这个函数不是异步的,执行起来需要花费很多时间,这会导致问题吗
看起来像这样:
public static bool isValidConnection(string url, string user, string password)
{
try
{
FtpClient client = new FtpClient(url);
client.Credentials = new NetworkCredential(user, password);
client.SocketPollInterval = 60000;
client.ConnectTimeout = 60000;
client.ReadTimeout = 60000;
client.DataConnectionConnectTimeout = 60000;
client.DataConnectionReadTimeout = 60000;
client.Connect();
bool IsItConnected = client.IsConnected;
if (IsItConnected == true)
{
client.Disconnect();
client.Dispose();
return true;
}
else
{
client.Disconnect();
client.Dispose();
return false;
}
}
catch(Exception ex)
{
LogWriter loger = new LogWriter(ex.ToString());
return false;
}
}
//编辑
Ftpclient来自FluentFTP库:首先,检查连接是否有效的方法根本不考虑取消令牌。如果它在执行网络操作时被阻止,即使您取消令牌,在它完成之前也不会发生任何事情。 如果FTP客户端占用了整个处理时间的大部分,并且没有接受CancellationToken的异步重载,那么它实际上是不可取消的,并且丢掉了您期望从CancellationToken中获得的所有优势 其次,如果取消发生在最里面的try块中,则您的
catch(Exception)
部分会抑制操作canceledexceptions。如果异常为OperationCanceledException,则应重新显示该异常
try
{
var DecryptedInfo = FileCryptoDecryptor.ReadEncryptedConfiguration("hakuna.xml.aes", Global_Variables.AppPassword);
string DecryptedFTPPass = EncryDecryptor.Decrypt(DecryptedInfo.FtpPassword, "blablabla");
token.ThrowIfCancellationRequested();
return General_Functions.isValidConnection(info.HDSynologyIP, info.FtpUsername, DecryptedFTPPass);
}
catch (Exception ex) when (!(ex is OperatiomCanceledException))
{
MessageBox.Show(ex.ToString());
}
首先,检查连接是否有效的方法根本不考虑取消令牌。如果它在执行网络操作时被阻止,即使您取消令牌,在它完成之前也不会发生任何事情。 如果FTP客户端占用了整个处理时间的大部分,并且没有接受CancellationToken的异步重载,那么它实际上是不可取消的,并且丢掉了您期望从CancellationToken中获得的所有优势 其次,如果取消发生在最里面的try块中,则您的
catch(Exception)
部分会抑制操作canceledexceptions。如果异常为OperationCanceledException,则应重新显示该异常
try
{
var DecryptedInfo = FileCryptoDecryptor.ReadEncryptedConfiguration("hakuna.xml.aes", Global_Variables.AppPassword);
string DecryptedFTPPass = EncryDecryptor.Decrypt(DecryptedInfo.FtpPassword, "blablabla");
token.ThrowIfCancellationRequested();
return General_Functions.isValidConnection(info.HDSynologyIP, info.FtpUsername, DecryptedFTPPass);
}
catch (Exception ex) when (!(ex is OperatiomCanceledException))
{
MessageBox.Show(ex.ToString());
}
如果在
MessageBox.Show上放置断点,当您单击按钮时,调试器是否会停止?你可能看不到消息,因为它在子线程中运行?@MickyD没有,但当我足够快地单击时,我会得到带有“操作被取消”的messagebox,这就是为什么如果你在messagebox上设置断点,我怀疑返回函数。Show
当你单击按钮时,调试器是否停止在那里?你可能看不到消息,因为它在子线程中运行?@MickyD没有,但当我足够快地单击时,我得到带有“操作被取消”的messagebox,这就是我怀疑返回函数的原因