Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 时代。如果代码可以在显示控件之前执行,或者出现致命的异常,则必须使用InvokeRequired。也许我太笨了,但这段代码无法编译。所以我按照自己构建的方式(VS2008)修复了它。只是为了完整性:在WPF中有一种不同的调度机制,但它的工作原理相当类似。您_C#_Multithreading_Winforms_Thread Safety_Invokerequired - Fatal编程技术网

C# 时代。如果代码可以在显示控件之前执行,或者出现致命的异常,则必须使用InvokeRequired。也许我太笨了,但这段代码无法编译。所以我按照自己构建的方式(VS2008)修复了它。只是为了完整性:在WPF中有一种不同的调度机制,但它的工作原理相当类似。您

C# 时代。如果代码可以在显示控件之前执行,或者出现致命的异常,则必须使用InvokeRequired。也许我太笨了,但这段代码无法编译。所以我按照自己构建的方式(VS2008)修复了它。只是为了完整性:在WPF中有一种不同的调度机制,但它的工作原理相当类似。您,c#,multithreading,winforms,thread-safety,invokerequired,C#,Multithreading,Winforms,Thread Safety,Invokerequired,时代。如果代码可以在显示控件之前执行,或者出现致命的异常,则必须使用InvokeRequired。也许我太笨了,但这段代码无法编译。所以我按照自己构建的方式(VS2008)修复了它。只是为了完整性:在WPF中有一种不同的调度机制,但它的工作原理相当类似。您可以在那里使用这个扩展方法:publicstaticvoid invokeFrequered(这个T ataTarget,Action aActionToExecute),其中T:DispatcherObject{if(ataTarget.Ch


时代。如果代码可以在显示控件之前执行,或者出现致命的异常,则必须使用
InvokeRequired
。也许我太笨了,但这段代码无法编译。所以我按照自己构建的方式(VS2008)修复了它。只是为了完整性:在WPF中有一种不同的调度机制,但它的工作原理相当类似。您可以在那里使用这个扩展方法:publicstaticvoid invokeFrequered(这个T ataTarget,Action aActionToExecute),其中T:DispatcherObject{if(ataTarget.CheckAccess()){aActionToExecute(ataTarget);}else{ataTarget.Dispatcher.Invoke(aActionToExecute);}我添加了一个答案,稍微简化了Lee的解决方案。嗨,当我使用类似的东西时,这个通用实现可能会产生一个大问题。如果控件是Disposition/Disposed,您将得到一个ObjectDisposedException。@Offler-如果它们是在不同的线程上处理的,那么您有一个同步问题,这不是此方法中的问题。使用
ISynchronizeInvoke
而不是
Control
不是更好吗?(向Jon Skeet致敬)@mike de clerk,我很关心你关于在(!control.Visible)…sleep..时添加
的建议。对我来说,这有一种糟糕的代码味道,因为它是一种潜在的无限延迟(在某些情况下甚至是无限循环),在代码中可能有调用方不希望出现这种延迟(甚至是死锁)。依我看,
Sleep
的任何使用都应由每个调用者负责,或者应该放在一个单独的包装中,并清楚地标明其后果。通常,最好是“硬失败”(异常,在测试期间捕获),或者在控件未准备好时“不做任何事情”。注释?while(!Visible)需要超时。错误的做法可能导致难以调试的无限循环。事实并非如此,因为我们正在调用winforms控件。另请参见@OlivierJacot Descombes,如果您能解释thread.invokerequired背后是如何工作的,那就太好了。嘿,谢谢您的回答。我问这个问题已经好几年了(和我和C#一起工作的时间差不多一样长),但我想知道你是否可以进一步解释一下?您链接到的文档引用了在控件被赋予句柄之前调用
invoke()
等的特定危险,但IMHO没有描述您所描述的内容。所有这些
invoke()
废话的全部要点是以线程安全的方式更新UI,我认为在阻塞上下文中放置更多指令会导致口吃?(呃……很高兴我停止使用M$tech。太复杂了!)我还想指出,尽管经常使用原始代码(早在那时),但我没有注意到您在我的双CPU桌面上描述的问题。我怀疑这个答案是否准确,因为MSDN显示了大量与OP类似的示例。
private void DoGUISwitch() {
    // cruisin for a bruisin' through exception city
    object1.Visible = true;
    object2.Visible = false;
}
private void DoGUISwitch() {
    if (object1.InvokeRequired) {
        object1.Invoke(new MethodInvoker(() => { DoGUISwitch(); }));
    } else {
        object1.Visible = true;
        object2.Visible = false;
    }
}
public static void InvokeIfRequired(this Control c, Action<Control> action)
{
    if(c.InvokeRequired)
    {
        c.Invoke(new Action(() => action(c)));
    }
    else
    {
        action(c);
    }
}
object1.InvokeIfRequired(c => { c.Visible = true; });
public static void InvokeIfRequired<T>(this T c, Action<T> action) 
    where T : Control
private void DoGUISwitch()
{ 
    Invoke( ( MethodInvoker ) delegate {
        object1.Visible = true;
        object2.Visible = false;
    });
} 
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <Header>
    <Title>ThreadsafeInvoke</Title>
    <Shortcut></Shortcut>
    <Description>Wraps code in an anonymous method passed to Invoke for Thread safety.</Description>
    <SnippetTypes>
      <SnippetType>SurroundsWith</SnippetType>
    </SnippetTypes>
  </Header>
  <Snippet>
    <Code Language="CSharp">
      <![CDATA[
      Invoke( (MethodInvoker) delegate
      {
          $selected$
      });      
      ]]>
    </Code>
  </Snippet>
</CodeSnippet>
public static void InvokeIfRequired(this Control control, MethodInvoker action)
{
    // See Update 2 for edits Mike de Klerk suggests to insert here.

    if (control.InvokeRequired) {
        control.Invoke(action);
    } else {
        action();
    }
}
richEditControl1.InvokeIfRequired(() =>
{
    // Do anything you want with the control here
    richEditControl1.RtfText = value;
    RtfHelpers.AddMissingStyles(richEditControl1);
});
public static void InvokeIfRequired(this ISynchronizeInvoke obj,
                                         MethodInvoker action)
{
    if (obj.InvokeRequired) {
        var args = new object[0];
        obj.Invoke(action, args);
    } else {
        action();
    }
}
// When the form, thus the control, isn't visible yet, InvokeRequired  returns false,
// resulting still in a cross-thread exception.
while (!control.Visible)
{
    System.Threading.Thread.Sleep(50);
}
delegate void ShowMessageCallback(string message);

private void Form1_Load(object sender, EventArgs e)
{
    ShowMessageCallback showMessageDelegate = new ShowMessageCallback(ShowMessage);
}

private void ShowMessage(string message)
{
    if (this.InvokeRequired)
        this.Invoke(showMessageDelegate, message);
    else
        labelMessage.Text = message;           
}

void Message_OnMessage(object sender, Utilities.Message.MessageEventArgs e)
{
    ShowMessage(e.Message);
}
private void DoGUISwitch() {
    if (object1.InvokeRequired) {
        object1.Invoke(new MethodInvoker(() => { DoGUISwitch(); }));
    } else {
        object1.Visible = true;
        object2.Visible = false;
    }
}
public delegate void InvokeIfRequiredDelegate<T>(T obj)
    where T : ISynchronizeInvoke;

public static void InvokeIfRequired<T>(this T obj, InvokeIfRequiredDelegate<T> action)
    where T : ISynchronizeInvoke
{
    if (obj.InvokeRequired)
    {
        obj.Invoke(action, new object[] { obj });
    }
    else
    {
        action(obj);
    }
} 
progressBar1.InvokeIfRequired(o => 
{
    o.Style = ProgressBarStyle.Marquee;
    o.MarqueeAnimationSpeed = 40;
});
    private void AddRowToListView(ScannerRow row, bool suspend)
    {
        if (IsFormClosing)
            return;

        if (this.InvokeRequired)
        {
            var A = new Action(() => AddRowToListView(row, suspend));
            this.Invoke(A);
            return;
        }
         //as of here the Code is thread-safe
control.InvokeIfRequired(c => c.Visible = false);

return control.InvokeIfRequired(c => {
    c.Visible = value

    return c.Visible;
});