System.Threading.Timer和Modal ShowDialog()的问题

时间:2017-01-11 14:59:02

标签: c# multithreading winforms timer

我有一个应用程序,其中我正在初始化Windows FormSystem.Threading.Timer

如果timer持续检查某些基于IPC的内容会遇到特定值,则会在同一个班级中发出event信号,然后调用ShowDialog()在早先初始化的对话框中。

不幸的是,此ShowDialog()Modal,会停止计时器。

我的印象是System.Threaded.Timer是在与调用线程不同的线程中创建的,因此Timer将继续在后台运行。

修改 - 部分代码

public delegate void EventHandler();
class someClass
{
    WrapperForm dlg = null;
    public void CallToChildThread(Object stateInfo)
    {
        AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
        //Check IPC
        //Fire event
        _show.Invoke();
    }
    public someClass()
    {
        public static event EventHandler _show;
        initializeDialog(); // Initialize the dialog. Standard new
        var autoEvent = new AutoResetEvent(false);
        var stateTimer = new System.Threading.Timer(CallToChildThread,
                                   autoEvent, 1000, 250);
        _show += new EventHandler(eventCheck);
    }
    void eventCheck()
    {
        //If some condition
        dlg.ShowDialog(); //Timer stops
    }
}

如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

System.Threading.Timer有一个已知的问题,如果你不保留对它的引用,即使在运行时它也可以被垃圾收集器收集。

切换到System.Timers.Timer,它只是System.Threading.Timer的包装,或者保留对计时器的引用,这样GC就不会收集它并取消你的计时器。

public delegate void EventHandler();
class someClass
{
    WrapperForm dlg = null;
    System.Threading.Timer stateTimer;
    public static event EventHandler _show;

    public void CallToChildThread(Object stateInfo)
    {
        AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
        //Check IPC
        //Fire event
        _show.Invoke();
    }
    public someClass()
    {
        initializeDialog(); // Initialize the dialog. Standard new
        var autoEvent = new AutoResetEvent(false);
        stateTimer = new System.Threading.Timer(CallToChildThread,
                                   autoEvent, 1000, 250);
        _show += new EventHandler(eventCheck);
    }
    void eventCheck()
    {
        //If some condition
        dlg.ShowDialog();
    }
}

答案 1 :(得分:1)

使用你的代码我改变了我的例子,我现在正在使用你的计时器(我仍在使用我的计时器,所以我可以看到另一个计时器仍在运行)

import urllib2
import re

def saveFile(url, fileName):
    request = urllib2.Request(url)
    response = urllib2.urlopen(request)
    with open(fileName,'wb') as handle:
        handle.write(response.read())

def main():
    base_url = 'https://www.electroimpact.com/Company/Patents/'
    page = 'https://www.electroimpact.com/Company/Patents.aspx'
    request = urllib2.Request(page)
    response = urllib2.urlopen(request)
    url_lst = re.findall('href.*(US.*\.pdf)', response.read())
    print url_lst

Result: 
    ['US5201205.pdf', 'US5279024.pdf', 'US5339598.pdf', 'US9021688B2.pdf']

它仍然适用于我,原因可能是因为我没有使计时器成为局部变量,而是在类中声明它。