Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.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# 网络浏览器控制赢得';当通过计时器调用时,t导航到URL_C#_Wpf_Multithreading_Timer_Webbrowser Control - Fatal编程技术网

C# 网络浏览器控制赢得';当通过计时器调用时,t导航到URL

C# 网络浏览器控制赢得';当通过计时器调用时,t导航到URL,c#,wpf,multithreading,timer,webbrowser-control,C#,Wpf,Multithreading,Timer,Webbrowser Control,我正在尝试用C#制作一个集成应用程序。我需要实现一些定期检查用户活动的功能,如果用户在一段时间内没有活动,它会将浏览器控件重定向回主页 下面是我的应用程序的代码片段。我正在使用该类定期调用CheckUserActivity方法,该方法只计算时间跨度,如果时间跨度大于某个阈值,它应该通过调用goHome方法重定向浏览器 不幸的是,这根本不起作用,而且这种行为对我来说相当奇怪。我添加了一些日志以查看实际发生的情况(见下文)。“应该马上离开”消息显示正常,但之后浏览器不会导航到主页,调用导航后的第二条

我正在尝试用C#制作一个集成应用程序。我需要实现一些定期检查用户活动的功能,如果用户在一段时间内没有活动,它会将浏览器控件重定向回主页

下面是我的应用程序的代码片段。我正在使用该类定期调用
CheckUserActivity
方法,该方法只计算时间跨度,如果时间跨度大于某个阈值,它应该通过调用
goHome
方法重定向浏览器

不幸的是,这根本不起作用,而且这种行为对我来说相当奇怪。我添加了一些日志以查看实际发生的情况(见下文)。“应该马上离开”消息显示正常,但之后浏览器不会导航到主页,调用
导航后的第二条消息也不会显示

我绝对没有错误。除了对webBrowser的
Navigate
方法的调用和之后的调用不知怎么消失之外,一切都正常工作。

我怀疑这个问题可能与线程有关,但我对C#的经验很少,所以我完全不知道这里可能存在什么问题

我还尝试使用
System.Threading.Tasks.Task
库重写代码,方法与
http://stackoverflow.com/questions/8267298/how-to-start-a-long-running-process-in-a-separate-thread
(sry用于代码块内的链接-信誉不足:D)。我将检查代码放入无限循环中,该循环作为长时间运行的任务运行,线程休眠两秒钟,但我遇到了完全相同的问题

非常感谢你的建议。下面是我的代码片段(它应该作为一个独立的项目工作):

XAML:

<Window x:Class="TimerTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="800" Width="800">
    <Grid>
        <WebBrowser x:Name="webBrowser" 
                            LoadCompleted="webBrowser_LoadCompleted"
                ></WebBrowser>
    </Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace TimerTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        private Uri URI_home;
        private Timer timer;
        private Uri URI_last;
        private DateTime lastUsed;

        public MainWindow()
        {
            URI_home = new Uri("http://example.com/", UriKind.RelativeOrAbsolute);
            URI_last = URI_home;

            InitializeComponent();

            webBrowser.Navigate(URI_home);

            // Create a timer with a two second interval.
            timer = new Timer(2000);
            // Hook up the Elapsed event for the timer. 
            timer.Elapsed += CheckUserActivity;
            timer.AutoReset = true;
            timer.Enabled = false;
            lastUsed = DateTime.Now;
        }

        private void goHome()
        {
            //System.Windows.Forms.MethodInvoker update = delegate()
            //{
            webBrowser.Navigate(URI_home);
            //};
            //webBrowser.invoke(update);
        }

        private void logMessage(string msg)
        {
            DateTime now = DateTime.Now;
            Console.WriteLine(now.ToString() + ": " + msg);
        }

        private void CheckUserActivity(Object source, ElapsedEventArgs e)
        {
            logMessage("Entered CheckUserActivity handler");
            DateTime now = DateTime.Now;
            TimeSpan timeSpan = now - lastUsed;
            logMessage("Timespan is " + timeSpan.Seconds.ToString());
            if (timeSpan.Seconds > 5 && URI_home != URI_last)
            {
                timer.Enabled = false;
                logMessage("Timer is now disabled.");
                logMessage("Will go away soon.");
                goHome();
                logMessage("Should have gone home");
            }
        }

        private void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
        {
            WebBrowser browser = (WebBrowser)sender;
            Uri URI_navigated = e.Uri;
            URI_last = URI_navigated;
            logMessage("WebBrowser LoadCompleted event triggered. LoadCompleted for URI (saved as URI_last): " + URI_navigated.AbsoluteUri);
            logMessage("Timer enabled status: " + timer.Enabled.ToString());
            lastUsed = DateTime.Now;
            timer.Enabled = true;
            logMessage("Timer is now enabled (end of LoadCompleted handler).");
        }
    }
}
浏览器启动后会导航到主页(example.com)。计时器已禁用,但在
LoadCompleted
处理程序结束时启用。用户逗留了一会儿,然后单击页面上的链接<代码>加载完成
被触发(计时器保持启用状态,因为我们还不必更改URL)。用户再次逗留,但这次不在主页上,条件在里面
CheckUserActivity
在一段时间后为真,计时器被禁用,浏览器应该导航回主页,但什么也没有发生。。。悲伤的故事:(

我怀疑您的计时器事件没有绑定到正确的计时器事件。 试试看

timer.Tick += CheckUserActivity;
编辑

可能是线程访问的问题:

private void goHome()
{
    MethodInvoker update = delegate()
    {
        webBrowser.Navigate(URI_home);
    };
    webBrowser.invoke(update);        
}

这是一个线程问题——如果用下面的方法替换goHome方法,它就会开始工作

享受:)


你有关于线程或其他东西的异常吗?@T00rk根本没有异常或错误。不要盲目地每2秒就把这些调用堆积起来;仅在
文档完成后触发它们
事件@TaW你能详细说明一下吗?我怀疑你从来没有让它完成过任何事情。就像一个用户不停地点击链接,从而阻塞了整个浏览器。在
DocumentCompleted
事件中启动计时器,并在
Elasped
事件中停止计时器。-(旁白:在某些情况下,使用两个计时器是有充分理由的,例如,一个用来启动,一个用来检测超时。)我使用的是System.Timers.Timer,它没有Tick属性。他写道,他使用的是'System.Timers.Timer',它没有通常的
Tick
!事件您确定事件已触发吗?@T00rk是的。我看到了我设置的第一个消息框,但没有看到调用浏览器的导航方法后的消息框。当使用此消息框时,我得到
“System.Windows.Controls.WebBrowser”不包含“invoke”的定义,并且找不到接受“System.Windows.Controls.WebBrowser”类型的第一个参数的扩展方法“invoke”(您是否缺少using指令或程序集引用?
在编译过程中…非常感谢!我有一种预感,它可能与线程有关,因为我在Java中遇到了类似的问题,但我不知道WPF中线程调度是如何工作的,所以我不确定如何修复它。
private void goHome()
{
    MethodInvoker update = delegate()
    {
        webBrowser.Navigate(URI_home);
    };
    webBrowser.invoke(update);        
}
private void goHome()
{
        Dispatcher.InvokeAsync(() => { webBrowser.Navigate(URI_home); });
}