我有一个第三方库,其中包含一个异步执行函数的类。该类继承自窗体。该函数基本上基于存储在数据库中的数据执行计算。一旦完成,它将调用调用窗体中的_Complete事件。
我想要做的是从非windows窗体应用程序同步调用该函数。问题是,无论我做什么,我的应用程序块和_Complete事件处理程序都不会触发。在windows窗体中,我可以使用"complete“标志和"while (!complete) application.doevents”来模拟同步运行的函数,但显然application.doevents在非windows窗体应用程序中不可用。
有没有什么东西会阻止我在windows窗体应用程序之外使用这个类的方法(因为它是从‘form’继承的)?有什么办法可以解决这个问题吗?
谢谢,迈克
发布于 2009-01-24 06:46:59
在一次尝试中,可能值得尝试下面这样的方法,它使用WaitHandle来阻塞当前线程,而不是旋转和检查标志。
using System;
using System.Threading;
class Program
{
AutoResetEvent _autoEvent;
static void Main()
{
Program p = new Program();
p.RunWidget();
}
public Program()
{
_autoEvent = new AutoResetEvent(false);
}
public void RunWidget()
{
ThirdParty widget = new ThirdParty();
widget.Completed += new EventHandler(this.Widget_Completed);
widget.DoWork();
// Waits for signal that work is done
_autoEvent.WaitOne();
}
// Assumes that some kind of args are passed by the event
public void Widget_Completed(object sender, EventArgs e)
{
_autoEvent.Set();
}
}
发布于 2009-01-28 02:47:17
我有更多关于这个问题的信息(我和mikecamimo在同一个团队工作)。
当正确复制时,Windows窗体应用程序中也会出现此问题。在最初的操作中,这个问题没有出现在windows窗体中,因为没有阻塞。当使用ResetEvent引入阻塞时,也会出现同样的问题。
这是因为事件处理程序(Widget_Completed)与调用Widget.DoWork的方法位于同一线程中。AutoResetEvent.WaitOne();永远阻塞的结果,因为从未调用事件处理程序来设置事件。
在windows窗体环境中,可以通过使用Application.DoEvents轮询消息队列并允许处理事件来解决此问题。见下文。
using System;
using System.Threading;
using System.Windows.Forms;
class Program
{
EventArgs data;
static void Main()
{
Program p = new Program();
p.RunWidget();
}
public Program()
{
_autoEvent = new AutoResetEvent(false);
}
public void RunWidget()
{
ThirdParty widget = new ThirdParty();
widget.Completed += new EventHandler(this.Widget_Completed);
data = null;
widget.DoWork();
while (data == null);
Application.DoEvents();
// do stuff with the results of DoWork that are contained in EventArgs.
}
// Assumes that some kind of args are passed by the event
public void Widget_Completed(object sender, EventArgs e)
{
data = e;
}
}
在非windows窗体应用程序中,应用程序不可用,因此无法调用DoEvents。
问题出在线程化上,而widget.DoWork的关联事件处理程序需要在另一个线程上。这应该可以防止AutoResetEvent.WaitOne无限期地阻塞。我想..。:)
任何关于如何实现这一点的想法都将是非常棒的。
发布于 2012-10-01 22:11:37
AutoResetEvent _autoEvent = new AutoResetEvent(false);
public WebBrowser SyncronNavigation(string url)
{
WebBrowser wb = null;
wb = new WebBrowser();
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
wb.ScriptErrorsSuppressed = true;
wb.Navigate(new Uri(url));
while (!_autoEvent.WaitOne(100))
Application.DoEvents();
return wb;
}
void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//throw new NotImplementedException();
_autoEvent.Set();
}
https://stackoverflow.com/questions/475617
复制相似问题