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#表单应用程序中使用BackGroundWorker更新UI线程_C#_Multithreading_User Interface_Backgroundworker_Invoke - Fatal编程技术网

在C#表单应用程序中使用BackGroundWorker更新UI线程

在C#表单应用程序中使用BackGroundWorker更新UI线程,c#,multithreading,user-interface,backgroundworker,invoke,C#,Multithreading,User Interface,Backgroundworker,Invoke,我有一个耗时的任务,测试几个网络连接。在下面的示例中,我将其限制为一个连接。 正常情况下,连接会很快返回,但可能会发生无法建立连接,导致套接字超时的情况。在此期间,我想在表单中显示一个“空闲”gif,当连接成功时,应用程序应该将表单中的图像更改为一些 绿色的检查图标或在连接失败的情况下,应显示红色图标“stopper” 不知何故,我无法使图像变得可见和生动。要模拟失败的连接,可以输入无效的端口或不存在的地址 有什么线索我遗漏了什么或做错了什么吗 partial class Form1

我有一个耗时的任务,测试几个网络连接。在下面的示例中,我将其限制为一个连接。 正常情况下,连接会很快返回,但可能会发生无法建立连接,导致套接字超时的情况。在此期间,我想在表单中显示一个“空闲”gif,当连接成功时,应用程序应该将表单中的图像更改为一些 绿色的检查图标或在连接失败的情况下,应显示红色图标“stopper”

不知何故,我无法使图像变得可见和生动。要模拟失败的连接,可以输入无效的端口或不存在的地址

有什么线索我遗漏了什么或做错了什么吗

    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        ///         
     #region BackgroundWorker

        private System.ComponentModel.BackgroundWorker backgroundWorker = new System.ComponentModel.BackgroundWorker();
        private delegate void SomeLongRunningMethodHandler(object sender, EventArgs e);

     #endregion
        private System.ComponentModel.IContainer components = null;

        Button button,button2;
        static Socket socket;
        static bool success;
        private static bool done;
        private Label lbl1;
        private Label lbl2;
        private TextBox address;
        private TextBox port;
        private PictureBox p;
        private static String port_number,host;


        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void RunTest(object o,EventArgs e)
        {
            p.Visible = true;
            SomeLongRunningMethodHandler synchronousFunctionHandler =
                default(SomeLongRunningMethodHandler);
            synchronousFunctionHandler = 
                TestConnection;
            synchronousFunctionHandler.Invoke(o, e);
        }

        private void TestConnection(object o, EventArgs e)
        {
            host = address.Text;
            port_number = port.Text;
           if (null != socket)
            {
                socket.Close();
            }

             Thread.Sleep(1000);
             IPEndPoint myEndpoint = new IPEndPoint(0, 0);


            IPHostEntry remoteMachineInfo = Dns.GetHostEntry(host);
            IPEndPoint serverEndpoint = new IPEndPoint(remoteMachineInfo.AddressList[0],
                int.Parse(port_number));



            socket = new Socket(myEndpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                socket.Connect(serverEndpoint);
                success = true;
                p.Image = global::BlockingUI.Properties.Resources.accept;
            }
            catch
            {
                success = false;
                p.Image = global::BlockingUI.Properties.Resources.stopper;
            }
            done = true;
        }  


        private void ExitApp(object o, EventArgs e)
        {
            Application.Exit();
        }

    }
部分类表单1
{
/// 
///必需的设计器变量。
/// 
///         
#区域背景工作者
private System.ComponentModel.BackgroundWorker BackgroundWorker=新系统.ComponentModel.BackgroundWorker();
私有委托void SomeLongRunningMethodHandler(对象发送方,EventArgs e);
#端区
private System.ComponentModel.IContainer components=null;
按钮,按钮2;
静态插座;
静态布尔成功;
私有静态布尔完成;
自有品牌lbl1;
自有品牌lbl2;
专用文本框地址;
专用文本框端口;
私人图片盒;
专用静态字符串端口号,主机;
/// 
///清理所有正在使用的资源。
/// 
///如果应释放托管资源,则为true;否则为false。
受保护的覆盖无效处置(布尔处置)
{
if(处理和(组件!=null))
{
组件。Dispose();
}
基地。处置(处置);
}
私有void运行测试(对象o、事件参数e)
{
p、 可见=真实;
SomeLongRunningMethodHandler synchronousFunctionHandler=
默认值(SomeLongRunningMethodHandler);
synchronousFunctionHandler=
测试连接;
synchronousFunctionHandler.Invoke(o,e);
}
私有void TestConnection(对象o、事件参数e)
{
host=address.Text;
端口号=port.Text;
if(null!=套接字)
{
socket.Close();
}
睡眠(1000);
IPEndPoint myEndpoint=新的IPEndPoint(0,0);
IPHostEntry remoteMachineInfo=Dns.GetHostEntry(主机);
IPEndPoint serverEndpoint=新IPEndPoint(remoteMachineInfo.AddressList[0],
int.Parse(端口号));
套接字=新套接字(myEndpoint.Address.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
尝试
{
socket.Connect(serverEndpoint);
成功=真实;
p、 Image=global::BlockingUI.Properties.Resources.accept;
}
抓住
{
成功=错误;
p、 Image=global::BlockingUI.Properties.Resources.stopper;
}
完成=正确;
}  
私有void exitap(对象o、事件参数e)
{
Application.Exit();
}
}

好吧,我是用自己的线程完成的。通常,您使用长时间运行的任务运行线程,并在需要时使用指向将在UI上运行的函数的委托调用Control.Invoke()。看起来您正在使用后台工作线程更改UI,这是不允许的


另外,在Winforms中,需要调用Control.Invalidate()来强制重新绘制UI并显示新图标。

好吧,我已经用自己的线程完成了这项工作。通常,您使用长时间运行的任务运行线程,并在需要时使用指向将在UI上运行的函数的委托调用Control.Invoke()。看起来您正在使用后台工作线程更改UI,这是不允许的


此外,在Winforms中,调用Control.Invalidate()强制重新绘制UI并显示新图标也是必要的。

如果您确实想使用
BackgroundWorker
,这(或接近它的东西),应该为您指明正确的方向。您正在创建一个
BackgroundWorker
对象,但却不使用它
BackgroundWorker
对象不允许访问UI元素,因为它们属于UI线程,但您可以传入UI值,就像我在这里使用
元组所做的那样(如果您愿意,您也可以创建自己的类来保存这些值),然后在工作完成后从UI线程修改UI

private struct ConnectionProperties
{
    public string Address;
    public string Port;
}

private void RunTest(object o, EventArgs e)
{
    BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();

    worker.RunWorkerCompleted += TestComplete;
    worker.DoWork += TestConnection;

    p.Visible = true;

    //worker.RunWorkerAsync(new Tuple<string, string>(address.Text, port.Text));
    worker.RunWorkerAsync(new ConnectionProperties{ Address = address.Text, Port = port.Text });
}

private void TestConnection(object sender, DoWorkEventArgs e)
{
    bool success = false;
    //var connection = e.Argument as Tuple<string, string>;
    var connection = (ConnectionProperties)e.Argument;

    if (null != socket)
    {
        socket.Close();
    }

    Thread.Sleep(1000);

    IPEndPoint myEndpoint = new IPEndPoint(0, 0);
    IPHostEntry remoteMachineInfo = Dns.GetHostEntry(connection.Address);
    IPEndPoint serverEndpoint = new IPEndPoint(remoteMachineInfo.AddressList[0],
      int.Parse(connection.Port));

    socket = new Socket(myEndpoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

    try
    {
        socket.Connect(serverEndpoint);
        success = true;
    }
    catch
    {
        success = false;
    }

    e.Result = success;
}

// Define other methods and classes here
private void TestComplete(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error == null)
    {
        var success = (bool)e.Result;
        if (success)
        {
            p.Image = global::BlockingUI.Properties.Resources.accept;
        }
        else
        {
            p.Image = global::BlockingUI.Properties.Resources.stopper;
        }
    }
    else
    {
        //unexpected error, show message or whatever
    }
}
私有结构连接属性
{
公共字符串地址;
公共字符串端口;
}
私有void运行测试(对象o、事件参数e)
{
BackgroundWorker worker=新系统.ComponentModel.BackgroundWorker();
worker.RunWorkerCompleted+=TestComplete;
worker.DoWork+=TestConnection;
p、 可见=真实;
//RunWorkerAsync(新元组(address.Text,port.Text));
worker.RunWorkerAsync(新连接属性{Address=Address.Text,Port=Port.Text});
}
私有void TestConnection(对象发送方,DoWorkEventArgs e)
{
布尔成功=假;
//var connection=e.参数作为元组;
var connection=(ConnectionProperties)e.参数;
if(null!=套接字)
{
socket.Close();
}
睡眠(1000);
IPEndPoint myEndpoint=新的IPEndPoint(0,0);
IPHostEntry remoteMachineInfo=Dns.GetHostEntry(connection.Address);
IPEndPoint serverEndpoint=新IPEndPoint(remoteMachineInfo.AddressList[0],
int.Parse(connection.Port));
套接字=新套接字(myEndpoint.Address.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
尝试
{
socket.Connect(serverEndpoint);
成功=t