只是想知道BeginInvoke()
和之间的区别Invoke()
是什么?
主要是每个人将用于什么.
编辑:创建一个线程对象和调用invoke并只调用BeginInvoke()
一个委托有什么区别?或者他们是一样的吗?
我正试着打电话System.Windows.Threading.Dispatcher.BeginInvoke
.方法的签名是这样的:
BeginInvoke(Delegate method, params object[] args)
Run Code Online (Sandbox Code Playgroud)
我试图传递一个Lambda而不是创建一个Delegate.
_dispatcher.BeginInvoke((sender) => { DoSomething(); }, new object[] { this } );
Run Code Online (Sandbox Code Playgroud)
它给了我一个编译错误说我
无法将lambda转换为System.Delegate.
委托的签名将对象作为参数并返回void.我的lambda匹配这个,但它不起作用.我错过了什么?
你能解释一下吗:
someformobj.BeginInvoke((Action)(() =>
{
someformobj.listBox1.SelectedIndex = 0;
}));
Run Code Online (Sandbox Code Playgroud)
你能告诉我怎么才能begininvoke
准确使用?什么是Action
类型?为什么有空白括号()
?这意味着=>
什么?
我有这个小方法应该是线程安全的.一切正常,直到我希望它具有回报价值而不是虚空.如何在调用BeginInvoke时获得返回值?
public static string readControlText(Control varControl) {
if (varControl.InvokeRequired) {
varControl.BeginInvoke(new MethodInvoker(() => readControlText(varControl)));
} else {
string varText = varControl.Text;
return varText;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我想在这种情况下让BeginInvoke不是nessecary,因为我需要来自GUI的值才能继续线程.所以使用Invoke也很好.只是不知道如何在以下示例中使用它来返回值.
private delegate string ControlTextRead(Control varControl);
public static string readControlText(Control varControl) {
if (varControl.InvokeRequired) {
varControl.Invoke(new ControlTextRead(readControlText), new object[] {varControl});
} else {
string varText = varControl.Text;
return varText;
}
}
Run Code Online (Sandbox Code Playgroud)
但不知道如何使用该代码获得价值;)
是否System.Windows.Threading.Dispatcher
适用于WinForms
应用程序的UI线程?
如果是,为什么?它来自WindowsBase.dll,它似乎是一个WPF
组件.
如果没有,我如何调用工作单元回到UI线程?我发现Control.BeginInvoke()
,但创建一个控件只是为了引用原始线程似乎很笨拙.
我很困惑为什么我不能让这个测试计数器应用程序使用Count()方法在我的Dispatcher上使用"BeginInvoke"的2个(或更多个)同时运行的反文本框.
您可以通过Invoke替换BeginInvoke来解决问题.但这并不能解决我的困惑.
这是我正在谈论的示例代码:
public class CounterTextBox : TextBox
{
private int _number;
public void Start()
{
(new Action(Count)).BeginInvoke(null, null);
}
private void Count()
{
while (true)
{
if (_number++ > 10000) _number = 0;
this.Dispatcher.BeginInvoke(new Action(UpdateText), System.Windows.Threading.DispatcherPriority.Background, null);
}
}
private void UpdateText()
{
this.Text = "" + _number;
}
}
Run Code Online (Sandbox Code Playgroud) 我想在做一些工作时显示进度条,但这会挂起UI并且进度条不会更新.
我有一个一个WinForm ProgressForm ProgressBar
将无限期地继续以滚动字幕的方式.
using(ProgressForm p = new ProgressForm(this))
{
//Do Some Work
}
Run Code Online (Sandbox Code Playgroud)
现在有很多方法可以解决这个问题,比如使用BeginInvoke
,等待任务完成和调用EndInvoke
.或使用BackgroundWorker
或Threads
.
我在使用EndInvoke时遇到了一些问题,尽管这不是问题.问题是哪种方法是用于处理此类情况的最佳和最简单的方法,您必须向用户显示程序正在运行而不是无响应,以及如何使用最简单的代码来处理这种情况,这样可以提高效率并赢得" t泄漏,可以更新GUI.
就像BackgroundWorker
需要有多个函数,声明成员变量等一样.然后你需要保持对ProgressBar表单的引用并处理它.
编辑:BackgroundWorker
不是答案,因为它可能是我没有得到进度通知,这意味着没有调用,ProgressChanged
因为DoWork
是对外部函数的单个调用,但我需要继续调用Application.DoEvents();
进度条保持旋转.
赏金是针对此问题的最佳代码解决方案.我只需要调用Application.DoEvents()
以便Marque进度条可以工作,而worker函数在Main线程中工作,并且它不会返回任何进度通知.我从不需要.NET魔术代码来自动报告进度,我只需要一个比以下更好的解决方案:
Action<String, String> exec = DoSomethingLongAndNotReturnAnyNotification;
IAsyncResult result = exec.BeginInvoke(path, parameters, null, null);
while (!result.IsCompleted)
{
Application.DoEvents();
}
exec.EndInvoke(result);
Run Code Online (Sandbox Code Playgroud)
保持进度条活着(意味着不冻结但刷新品牌)
MS文档中的此页面,包括Windows窗体应用程序中的异步,指出:
如果需要,可以调用EndInvoke从委托中检索返回值,但这不是必需的.(重点补充)
这个页面涵盖了异步委托的一般情况,说明了一些不同的东西:
无论使用哪种技术,始终调用EndInvoke来完成异步调用.
这两者似乎存在直接冲突.
这是真的吗?谁能解释一下?
我已经阅读了几个论坛,甚至还有一个或两个stackoverflow问题,说使用Delegate.BeginInvoke时需要Delegate.EndInvoke.我读过的很多关于使用BeginInvoke的文章都未提及使用EndInvoke.此外,我仅使用BeginInvoke部署了生产代码,并且似乎没有任何内存问题.我使用BeginInvoke的方式通常是线程,我不关心它们完成或处理多长时间.
为什么不能将匿名方法作为参数传递给BeginInvoke
方法?我有以下代码:
private delegate void CfgMnMnuDlg(DIServer svr);
private void ConfigureMainMenu(DIServer server,)
{
MenuStrip mnMnu = PresenterView.MainMenu;
if (mnMnu.InvokeRequired)
{
mnMnu.BeginInvoke((CfgMnMnuDlg)ConfigureMainMenu,
new object[] { server});
}
else
{
// Do actual work here
}
}
Run Code Online (Sandbox Code Playgroud)
我试图避免宣布代表.为什么我不能写下面的东西呢?或者我可以,我只是无法弄清楚正确的语法?以下目前生成:
参数类型'System.Delegate'不能赋予参数类型'匿名方法'
好吧,这当然是正确的,但我是否可以使用其他语法来做到这一点(避免为了使用而必须声明一个单独的委托BeginInvoke()
?
(能够做到这一点将完全符合使用anon方法/ lamdas代替显式委托的概念,这些委托在其他地方干净利落地工作.)
private void ConfigureMainMenu(DIServer server,)
{
MenuStrip mnMnu = PresenterView.MainMenu;
if (mnMnu.InvokeRequired)
{
mnMnu.BeginInvoke( // pass anonymous method instead ?
delegate(DIServer svr) { ConfigureMainMenu(server);},
new object[] { server});
}
else
{
// Do actual work here
}
}
Run Code Online (Sandbox Code Playgroud) begininvoke ×10
c# ×7
.net ×4
dispatcher ×3
invoke ×3
delegates ×2
.net-3.5 ×1
lambda ×1
winforms ×1
wpf ×1