我继承了从主线程调用BeginInvoke的代码(不是后台线程,通常是模式).我试图了解它在这种情况下的实际作用.
在BeginInvoke中调用的方法是否符合到窗口的消息?文档说asynchronously,这是我的假设.
框架如何确定何时启动BeginInvoke调用的方法?
编辑:代码如下所示:
System.Action<bool> finalizeUI = delegate(bool open)
{
try
{
// do somewhat time consuming stuff
}
finally
{
Cursor.Current = Cursors.Default;
}
};
Cursor.Current = Cursors.WaitCursor;
BeginInvoke(finalizeUI, true);
Run Code Online (Sandbox Code Playgroud)
这发生在Form_Load事件中.
我有两个线程的应用程序.其中一个(T1)是主GUI形式,另一个(T2)是循环中的功能.当T2得到一些信息必须用GUI形式调用函数.我不确定我做得对.
T2调用函数FUNCTION,以GUI形式更新某些内容.
public void f() {
// controler.doSomething();
}
public void FUNCTION() {
MethodInvoker method = delegate {
f();
};
if ( InvokeRequired ) {
BeginInvoke( method );
} else {
f();
}
}
Run Code Online (Sandbox Code Playgroud)
但现在我必须宣布两个功能.它如何只使用一个功能?或者它是如何正确的.
可能重复:
每个BeginInvoke必须跟一个EndInvoke吗?
EndInvoke()是可选的,sort-of optional,还是绝对不是可选的?
我有一个多线程应用程序,其中一个辅助线程需要每隔几分钟就在主线程上执行一些代码.没有任何返回值,第二个线程不关心它是否引发任何异常或无法运行.
到目前为止,我已经得到它来运行代码Form.Invoke,但它有时需要比平时(几秒钟)更长的时间并阻塞线程直到它完成.我需要第二个线程能够继续执行而不会停顿几秒钟.
BeginInvoke听起来它很好地完成了工作,但我真的没有任何地方可以打电话EndInvoke,因为我不想等待它或获得返回值.考虑到被调用的代码涉及一堆本机调用,我不确定它是否是一个好主意EndInvoke.
我是否需要调用EndInvoke,或者是否有其他方法可以使代码在主窗体线程上异步运行而不是我应该使用?
谢谢=)
我对跨线程访问遇到的场景感到困惑.这是我想要做的:
主UI线程 - 菜单项单击我创建后台工作程序并异步运行它
private void actionSubMenuItem_Click(object sender, EventArgs e)
{
ToolStripMenuItem itemSelected = (ToolStripMenuItem)sender;
ExecuteTheActionSelected(itemSelected.Text);
}
Run Code Online (Sandbox Code Playgroud)
方法ExecuteTheActionSelected如下:
private void ExecuteTheActionSelected(string actionSelected)
{
BackgroundWorker localBackgroundWorker = new BackgroundWorker();
localBackgroundWorker.DoWork += new DoWorkEventHandler(localBackgroundWorker_DoWork);
localBackgroundWorker.RunWorkerAsync(SynchronizationContext.Current);
}
Run Code Online (Sandbox Code Playgroud)
该localBackgroundWorker_DoWork有:
ActionExecutionHelper actionExecutioner = new ActionExecutionHelper()
actionExecutioner.Execute();
Run Code Online (Sandbox Code Playgroud)
的Execute在于类具有INFACT调用在UI线程的事件处理方法调用方法:
public void Execute()
{
// ---- CODE -----
new MethodInvoker(ReadStdOut).BeginInvoke(null, null);
}
protected virtual void ReadStdOut()
{
string str;
while ((str = executionProcess.StandardOutput.ReadLine()) != null)
{
object sender = new object();
DataReceivedEventArgs …Run Code Online (Sandbox Code Playgroud) 是否可以在"火与忘"方式之外使用Control.BeginInvoke?我想更改以下请求以委托回调方法,以便我可以在每个异步调用完成时执行某些操作.
this.BeginInvoke(new RefreshRulesDelegate(RefreshRules), new object[] { ctrl, ctrl.DsRules, ctrl.CptyId });
Run Code Online (Sandbox Code Playgroud)
我可以用普通的delegate.BeginInvoke这样做
RefreshRulesDelegate del = new RefreshRulesDelegate(RefreshRules);
del.BeginInvoke(ctrl, ctrl.DsRules, ctrl.CptyId, new AsyncCallback(RefreshCompleted), del);
Run Code Online (Sandbox Code Playgroud)
但因为我正在调用Control .BeginInvoke,因为我得到"跨线程操作无效"错误,所以无法执行此操作.
有人帮吗?
对于收到的一些答案,我将澄清"为什么".我需要在我的GUI上加载/刷新一个Control,而不需要锁定应用程序的其余部分.该控件包含许多控件(ruleListCtls),这些控件都需要检索数据集并将其传递给它们.即
public void RefreshAll()
{
foreach (LTRFundingRuleListControl ctrl in ruleListCtls)
{
this.BeginInvoke(new RefreshRulesDelegate(RefreshRules), new object[]{ctrl,ctrl.DsRules, ctrl.CptyId });
}
}
Run Code Online (Sandbox Code Playgroud)
我发现如果我提供一个委托回调方法并将修改控件的任何代码移回到创建它们的主GUI线程上(以避免跨线程错误),我可以这样做
public void RefreshAll()
{
IntPtr handle;
foreach (LTRFundingRuleListControl ctrl in ruleListCtls)
{
handle = ctrl.Handle;
RefreshRulesDsDelegate del = new RefreshRulesDsDelegate(RefreshRulesDs);
del.BeginInvoke(ctrl.DsRules, ctrl.CptyId, handle, out handle, new AsyncCallback(RefreshCompleted), del);
}
}
private void RefreshCompleted(IAsyncResult result) …Run Code Online (Sandbox Code Playgroud) 我需要一种同步执行某些操作的方法,该操作应在半秒内完成,但可能只会停留几分钟。如果超时我不在乎结果。这是我现在正在使用编译器生成的 delegate.BeginInvoke 执行的操作:
static void Main()
{
bool disposed = false;
var wait = new ManualResetEvent(false);
var a = new Action(
() =>
{
Thread.Sleep(1000); // <- some looong action
if (!disposed)
lock (wait)
if (!disposed)
wait.Set();
});
a.BeginInvoke(a.EndInvoke, null);
bool success = wait.WaitOne(500);
Console.WriteLine(success ? "success" : "timeout");
lock (wait)
{
wait.Dispose();
disposed = true;
}
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
看起来很丑。我知道 lambda 闭包的disposed变量已被修改(与我的 ReSharper 不同,我喜欢这个 C# 功能)。一切都是因为我想处置掉ManualResetEvent。您能建议 .NET4 中更好的方法吗?也许我应该跳过处理事件并依赖 GC?
需要注意的是:ManualResetEvent.Set()如果您尝试在已处置的实例上执行此操作,则会爆炸。
当我向Dispatcher调用许多方法时,比如说UI线程的Dispatcher,
像这儿
uiDispatcher.BeginInvoke(new Action(insert_), DispatcherPriority.Normal);
uiDispatcher.BeginInvoke(new Action(add_), DispatcherPriority.Normal);
uiDispatcher.BeginInvoke(new Action(insert_), DispatcherPriority.Normal);
Run Code Online (Sandbox Code Playgroud)
这些方法是否会以我调用它们的顺序执行?
我正在尝试写一个非常简单的异步代码.我有一个void方法,它不接受任何参数,这些参数是从Windows服务调用的.我想把它打开异步,这样服务就不必等待方法完成了.
我创建了一个非常简单的测试应用程序,以确保我正在编码正确,但异步方法只是没有被调用.任何人都能看到我做错了什么?我顺便使用.NET 4.0,所以我不能使用await(这会更简单!).
这是我的整个测试样本......
using System;
using System.Threading;
namespace AsyncCallback {
internal class Program {
private static void Main(string[] args) {
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - About to ask for stuff to be done");
new Action(DoStuff).BeginInvoke(ar => StuffDone(), null);
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Asked for stuff to be done");
}
private static void StuffDone() {
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Stuff done");
}
private static void DoStuff() {
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Starting to do stuff");
Thread.Sleep(1000);
Console.WriteLine(DateTime.Now.ToLocalTime().ToLongTimeString() + " - Ending …Run Code Online (Sandbox Code Playgroud) 我有一个控件,显示底层异步对象的状态.该对象引发事件,这些事件到达表单,它们基本上排队并最终使用BeginInvoke调用.
当处理控制时出现问题.因为事情是异步发生的,意味着事件回调总是可能在处理过程中排队,我有时会得到一个InvalidOperationException(在创建窗口句柄之前,不能在控件上调用Invoke或BeginInvoke).
这不是我想要的行为.我希望回调执行即使控件已被释放(即使这会导致回调中的异常;这对我来说是一个更有用的例外!).我想处理每个回调中的处理状态行为(通常只是在处理时跳过,但有时不会[例如,一个控件记录事件(可选地记录到文件)并且我不想丢失日志数据!].).
有没有一种方法可以按我想要的方式工作?我可以自己写一个不易碎的吗?
根据 MSDN 的说法,它提供了管理线程工作项队列的服务。Dispatcher
一个简单的问题。我想仅用Dispatcher于此目的:作为工作项队列(通过发布Dispatcher.BeginInvoke),我的后台线程将以串行方式提供服务。
我不想让这个线程成为 STA 线程,也不需要在其上发送 Windows 消息。该线程上不会有 UI。
这是合法的使用方式吗Dispatcher?
begininvoke ×10
c# ×9
.net ×3
asynchronous ×2
winforms ×2
.net-2.0 ×1
action ×1
controls ×1
delegates ×1
dispatcher ×1
invoke ×1
synchronous ×1
threadpool ×1
timeout ×1
wpf ×1