我正在尝试为我的webclient实现超时。客户端正在做的就是检查是否存在与服务器的连接。该部分工作正常,但默认情况下不会超时。这就是我试图实现取消异步调用的计时器的原因。这是代码:
namespace WPCordovaClassLib.Cordova.Commands
{
public class BasicAuth : BaseCommand
{
//Create timer to control timeout
DispatcherTimer timeoutTimer = new DispatcherTimer();
WebClient webClient = new WebClient();
public void get(string options)
{
//Parse data that gets passed into the plugin
string[] passedData = JSON.JsonHelper.Deserialize<string[]>(options);
//save data to variables
try
{
//Set interval for timer, add event handler and start timer
timeoutTimer.Interval = TimeSpan.FromSeconds(5);
timeoutTimer.Tick += new EventHandler(timeout);
timeoutTimer.Start();
}
catch (Exception e)
{
System.Diagnostics.Debug.WriteLine(e);
}
try
{
webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
//Define credentials, set header etc.
webClient.DownloadStringAsync(uri);
}
catch (Exception ex)
{
//Catch exception and react
}
}
void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try{
//Do stuff
} catch{
//Do stuff
}
finally
{
timeoutTimer.Stop();
}
}
private void timeout(Object sender, EventArgs e)
{
timeoutTimer.Stop(); //Stop timer from beeing executed again
webClient.CancelAsync(); //Cancel Async download
//handle timeout
}
}
}
所以我的想法是启动计时器,如果该计时器第一次打勾(在这种情况下是5秒后),请停止计时器,取消Async-part并处理超时。 不幸的是,当我创建计时器时,我得到的是以下异常:
mscorlib.ni.dll中出现“System.IO.FileNotFoundException”类型的异常(第一次机会)。
System.Windows.ni.dll中出现“System.UnauthorizedAccessException”类型的异常(第一次机会)。
System.UnauthorizedAccessException:无效的跨线程访问。
在MS.Internal.XcpImports.CheckThread()
at MS.Internal.XcpImports.SetValue(IManagedPeerBase obj,DependencyProperty property,String s)
at System.Windows.Threading.DispatcherTimer.set_Interval(TimeSpan value)
at WPCordovaClassLib.Cordova.Commands.BasicAuth.get(String options)
之前我还没有真正使用过C#,因此可能会有更简单或更好的解决方案。
答案 0 :(得分:0)
这是基于异常消息的建议。尽量避免在get方法中设置timeoutTimer的属性。如果可能,为BasicAuth创建一个无参数构造函数并将这些行移动到那里
timeoutTimer.Interval = TimeSpan.FromSeconds(5);
timeoutTimer.Tick += new EventHandler(timeout);
有点猜测,但希望这项工作。
答案 1 :(得分:0)
har07-tip解决了这个问题。
在构造函数中放置这两行以及计时器的开头似乎确实更好。取消Async-part实际上也是由我的DownloadString方法的事件处理程序处理的。我已经在timeout-method中停止了计时器,而在webClient_DownloadStringCompleted-method中再次停止计时器。
由于计时器已在此处停止,因此引发了异常。我引入了一个额外的布尔值来看看我来自哪里并采取相应的行动。