我有以下代码:
Public Delegate Sub SetStatusBarTextDelegate(ByVal StatusText As String)
Private Sub SetStatusBarText(ByVal StatusText As String)
If Me.InvokeRequired Then
Me.Invoke(New SetStatusBarTextDelegate(AddressOf SetStatusBarText), StatusText)
Else
Me.labelScanningProgress.Text = StatusText
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
问题是,当我从另一个线程调用"SetStatusBarText"子时,InvokeRequired为True(应该是),但是然后我的线程在Me.Invoke语句中停止 - 暂停执行显示它们只是坐在那里,而不是实际调用任何东西.
关于为什么线程似乎害怕Invoke的任何想法?
要弹出一个消息框,我正在使用MessageBox.Show(...).我通常将调用包装在一个Invoke中:
BeginInvoke (new Action (() => {
MessageBox.Show ());
}));
Run Code Online (Sandbox Code Playgroud)
(我删除了其他地方回答的原问题的一部分)
Invoke如果我从非GUI线程调用,是否总是需要将MessageBox调用包装在(Begin-)中?
我想调用一个操作UI线程控件的方法.我的代码有效,我想优化.我指的是MSDN上的这个资源.
根据那里,我们应该这样做
public delegate void myDelegate(int anInteger, string aString);
//...
Label1.Invoke(new myDelegate(myMethod), new Object[] {1, "This is the string"});
Run Code Online (Sandbox Code Playgroud)
这会在每次调用时引入一个孤立的委托对象(内存泄漏)吗?
当我像下面这样使用委托的静态实例时,然后在每次调用时使用此实例来调用:
private static _delegateInstance = new myDelegate(myMethod);
//...
Label1.Invoke(_delegateInstance , new Object[] {1, "This is the string"});
Run Code Online (Sandbox Code Playgroud)
这是线程安全吗?我认为这会有更好的性能,因为委托实例只创建一次?
VB.NET 2010,.NET 4
你好,
我最近读到了使用SynchronizationContext对象来控制某些代码的执行线程.我一直在使用通用子例程来处理(可能)跨线程调用,例如更新使用的UI控件Invoke.我是一名业余爱好者,很难理解任何特定方法的优缺点.我正在寻找一些有关哪种方法可能更可行以及为什么更有用的见解.
更新:此问题的部分原因在于MSDN页面中Control.InvokeRequired的以下语句.
更好的解决方案是使用
SynchronizationContext返回的SynchronizationContext而不是控件来进行跨线程编组.
而且,对于为什么,在我看来,大多数关于SO上此类问题的问题的答案的建议都提出了Invoke这种方法,并没有提到这种方法.
方法1:
Public Sub InvokeControl(Of T As Control)(ByVal Control As T, ByVal Action As Action(Of T))
If Control.InvokeRequired Then
Control.Invoke(New Action(Of T, Action(Of T))(AddressOf InvokeControl), New Object() {Control, Action})
Else
Action(Control)
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
方法2:
Public Sub UIAction(Of T As Control)(ByVal Control As T, ByVal Action As Action(Of Control))
SyncContext.Send(New Threading.SendOrPostCallback(Sub() Action(Control)), Nothing)
End Sub
Run Code Online (Sandbox Code Playgroud)
在我的UI表单的构造函数中定义SyncContext的Threading.SynchronizationContext …
好吧,假设我有b.exe,它接受一个字符串参数.我想在a.cpp中使用系统调用b.exe:
string s1 = "hallo";
system("b.exe s1");
printf("s1 after invoke = %s",s1);
Run Code Online (Sandbox Code Playgroud)
这是b.cpp中的代码:
int main(string s)
{
s = "hello world";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想要的是,当我运行a.exe时,输出将是:
s1 after invoke = hello world
Run Code Online (Sandbox Code Playgroud)
有可能这样做吗?基本上,我只是想将一个变量传递给一个exe,但它必须通过引用,而不仅仅是值,因为我希望在我调用的exe中处理和修改该变量.我已经在互联网上搜索了解决方案,但它只提供了一种方法,可以通过值将变量传递给exe,而不是通过引用.
任何建议将非常感激,但如果可能的话,我希望以上述更正代码的形式提出建议,并包括文件,如果有的话.谢谢你的帮助 :)
试图从其他线程更新UI控件.
目前正在使用BeginInvoke,老实说它工作正常,但我一直听说你如何使用SynchronizationContext来做同样的事情.
哪个更受欢迎?
另外,从线程更新UI是不好的做法吗?提出一个事件并让主要表单处理它或者还有其他更好的方法来处理它会更好吗?
对不起,我有些主观的问题,但在线程的世界这么多的选择,我试图抓住他们的分歧,每个人都适用,与写可读和可扩展的代码对未来的最佳实务.
编辑:现在我也看到了TaskScheduler.FromCurrentSynchronizationContext路线也是如此..有很多选择x_x
我们有一个应用程序,它使用MBeanServerConnection.invoke在MBean上调用各种远程方法.偶尔会有其中一种方法挂起.有没有办法让电话超时?如果通话时间太长,它将返回异常?
或者我是否必须将所有这些调用移动到单独的线程中,以便它们不会锁定UI并要求杀死应用程序?
任何人都可以帮助我,我有一个问题我试图让这个代码通过线程池在后台工作,但我似乎无法让它工作我一直收到此错误:
Cross-thread operation not valid: Control 'ListBox3' accessed
from a thread other than the thread it was created on.
Run Code Online (Sandbox Code Playgroud)
这是我正在使用的代码:
private void DoWork(object o)
{
var list = ListBox3;
var request = createRequest(TxtServer.Text, WebRequestMethods.Ftp.ListDirectory);
using (var response = (FtpWebResponse)request.GetResponse())
{
using (var stream = response.GetResponseStream())
{
using (var reader = new StreamReader(stream, true))
{
while (!reader.EndOfStream)
{
list.Items.Add(reader.ReadLine());
ResultLabel.Text = "Connected";
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 我使用powershell命令来执行脚本和cmdlet.因此,在执行cmdlet时,我使用了powershell.invoke,在执行脚本时,我使用了pipeline.invoke方法.我想知道System.Management.Automation.pipeline.invoke()方法和System.Management.Automation.Runspaces.powershell.invoke()方法之间是否有任何区别.
我有两个WinForms(Setting和frmMain).我在Setting的表单中有一个TreeView,我想以FillTree第二种形式调用它的方法frmMain.
我正在使用它TreeView.Invoke来进行线程化.
这是我在Setting的表单中填充TreeView的代码:
TreeNode parentNode;
public void FillTree(DataTable dtGroups, DataTable dtGroupsChilds)
{
treeViewGroups.Nodes.Clear();
if (dtGroups == null) return;
foreach (DataRow rowGroup in dtGroups.Rows)
{
parentNode = new TreeNode
{
Text = rowGroup["Groupname"].ToString(),
Tag = rowGroup["Groupid"]
};
treeViewGroups.Invoke(new Add(AddParent), new object[] { parentNode });
if (dtGroupsChilds == null) continue;
foreach (DataRow rowUser in dtGroupsChilds.Rows)
{
if (rowGroup["Groupid"] == rowUser["Groupid"])
{
TreeNode childNode = new TreeNode
{
Text = rowUser["Username"].ToString(),
Tag = …Run Code Online (Sandbox Code Playgroud)