更新在C#窗体应用程序使用BackgroundWorker的UI线程 [英] updating UI thread using BackGroundWorker in C# Form application

查看:139
本文介绍了更新在C#窗体应用程序使用BackgroundWorker的UI线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个耗时的任务,测试了几个网络连接。在我的例子下面我把它局限在一个连接。
常连接迅速返回,但它可能发生的连接不能进行,以便从插座次。在这段时间里,我想以显示形式的闲人的gif,当连接成功的应用程序应在表格改变图像的一些
绿色选中图标或在失败的连接红色图标的情况下, 应显示瓶塞。



不知怎的,我不能让惰GIF变得可见和动画。为了模拟一个失败的连接可以输入无效端口号或不存在的地址。



任何线索什么我丢失或做错了什么?



 部分Form1类
{
///<总结>
///必需的设计变量。
///< /总结>
///
#地区的BackgroundWorker

私人System.ComponentModel.BackgroundWorker BackgroundWorker的=新System.ComponentModel.BackgroundWorker();
私人委托无效SomeLongRunningMethodHandler(对象发件人,EventArgs e)条;

#endregion
私人System.ComponentModel.IContainer成分= NULL;

按钮,按钮2;
静态Socket套接字;
静态布尔成功;
私人静态布尔做的;
自有品牌LBL1;
自有品牌LBL2;
私人文本框地址;
私人文本框口;
私人PictureBox的磷;
私人静态字符串端口号,主机;


///<总结>使用
///清理的任何资源。
///< /总结>
///< PARAM NAME =处理>真要是托管资源应释放;否则为false< /参数>
保护覆盖无效的Dispose(BOOL处置)
{
如果(处置和放大器;及(成分= NULL)!)
{
components.Dispose();
}
base.Dispose(处置);
}

私人无效的runTest(对象o,EventArgs五)
{
p.Visible = TRUE;
SomeLongRunningMethodHandler synchronousFunctionHandler =
默认(SomeLongRunningMethodHandler);
synchronousFunctionHandler =
TestConnection;
synchronousFunctionHandler.Invoke(O,E);
}

私人无效TestConnection(对象o,EventArgs五)
{
主机= address.Text;
端口号= port.Text;
如果(空=插座!)
{
socket.Close();
}

Thread.sleep代码(1000);
IPEndPoint myEndpoint =新IPEndPoint(0,0);


IPHostEntry remoteMachineInfo = Dns.GetHostEntry(主机);
IPEndPoint serverEndpoint =新IPEndPoint(remoteMachineInfo.AddressList [0],
int.Parse(端口号));



插座=新的Socket(myEndpoint.Address.AddressFamily,SocketType.Stream,ProtocolType.Tcp);

{
socket.Connect(serverEndpoint);
成功= TRUE;
p.Image =全​​球:: BlockingUI.Properties.Resources.accept;
}

{
成功= FALSE;
p.Image =全​​球:: BlockingUI.Properties.Resources.stopper;
}
进行= TRUE;
}


私人无效ExitApp命令(对象o,EventArgs五)
{
Application.Exit();
}

}


解决方案

如果你真的想使用的BackgroundWorker ,这个(或接近它),应该指向你在正确的方向。您正在创建一个的BackgroundWorker 的对象,但然后什么都不做吧。 的BackgroundWorker 对象是不允许,因为它们是由UI线程拥有访问UI元素,但你可以在UI值传递,因为我有一个元组(你可以创建自己的类,如果你想太多持有这些值),然后修改从UI线程一旦工人完成的UI。

 私人结构的ConnectionProperties 
{
公共字符串地址;
公共字符串端口;
}

私人无效的runTest(对象o,EventArgs五)
{
BackgroundWorker的工人=新System.ComponentModel.BackgroundWorker();

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

p.Visible = TRUE;

//worker.RunWorkerAsync(new元组LT;字符串,字符串>(address.Text,port.Text));
worker.RunWorkerAsync(新ConnectionProperties中{地址= address.Text,端口= port.Text});
}

私人无效TestConnection(对象发件人,DoWorkEventArgs E)
{
BOOL成功= FALSE;
// VAR连接= e.Argument的元组LT;字符串,字符串取代;
VAR连接=(ConnectionProperties中)e.Argument;

如果(空=插座!)
{
socket.Close();
}

Thread.sleep代码(1000);

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

插座=新的Socket(myEndpoint.Address.AddressFamily,SocketType.Stream,ProtocolType.Tcp);


{
socket.Connect(serverEndpoint);
成功= TRUE;
}

{
成功= FALSE;
}

e.Result =成功;
}

//定义其它的方法和类在这里
私人无效TestComplete(对象发件人,RunWorkerCompletedEventArgs E)
{
如果(e.Error = = NULL)
{
VAR成功=(布尔)e.Result;
如果(成功)
{
p.Image =全​​球:: BlockingUI.Properties.Resources.accept;
}
,否则
{
p.Image =全​​球:: BlockingUI.Properties.Resources.stopper;
}
}
,否则
{
//意外的错误,显示消息或任何
}
}


I have a time consuming task that tests a couple of network connections. In my example below I have confined it to one connection. Normally the connection returns quickly but it could happen that the connection cannot be made so that the socket times out. During this time I would like to display an "idler" gif in the Form, when the connection succeeds the app should change the Image in the Form to some green check icon or in case of a failing connection a red icon "stopper" should be displayed.

Somehow I cannot get the idler gif become visible and animated. To simulate a failing connection one can enter an invalid port # or non existent address.

Any clues what I'm missing or doing wrong?

    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();
        }

    }

解决方案

If you truly want to use a BackgroundWorker, this (or something close to it), should point you in the right direction. You are creating a BackgroundWorker object but then doing nothing with it. BackgroundWorker objects are not allowed to access UI elements as they are owned by the UI thread, but you can pass in UI values, as I do here with a Tuple (you could create your own class to hold these values if you want too) and then modify the UI from the UI thread once the worker is complete.

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
    }
}

这篇关于更新在C#窗体应用程序使用BackgroundWorker的UI线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆