WPF中的C#:DispatcherTimer - System.UnauthorizedAccessException:无效的跨线程访问

时间:2013-11-30 16:12:47

标签: c# cordova windows-phone-8 timer windows-phone

我正在尝试为我的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#,因此可能会有更简单或更好的解决方案。

2 个答案:

答案 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中再次停止计时器。

由于计时器已在此处停止,因此引发了异常。我引入了一个额外的布尔值来看看我来自哪里并采取相应的行动。