Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.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#_Wpf_Multithreading_Backgroundworker - Fatal编程技术网

C# BackgroundWorker()运行时,UI挂起

C# BackgroundWorker()运行时,UI挂起,c#,wpf,multithreading,backgroundworker,C#,Wpf,Multithreading,Backgroundworker,我在wpf应用程序中使用BackgroundWorker进行线程处理。但它使UI挂起,因为我无法单击UI的任何地方。以下是我的代码片段: private void Window_Loaded(object sender, RoutedEventArgs e) { BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += delegate(object s, DoWorkEventA

我在wpf应用程序中使用BackgroundWorker进行线程处理。但它使UI挂起,因为我无法单击UI的任何地方。以下是我的代码片段:

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        BackgroundWorker worker = new BackgroundWorker();
        worker.DoWork += delegate(object s, DoWorkEventArgs args)
        {
            Dispatcher.Invoke(new Action(() => ConnectFtp()));
        };
        worker.RunWorkerAsync();
    }

private void ConnectFtp()
{
     try
        {
            int port = string.IsNullOrEmpty(txtport.Text) ? 21 : Convert.ToInt32(txtport.Text);
            if (ftpserver1 == null)
            {
                ftpserver1 = new FtpClient(txtftpserver.Text, port);
                ftpserver1.ServerResponse += new EventHandler<FtpResponseEventArgs>(ftpserver2_ServerResponse);
                ftpserver1.ClientRequest += new EventHandler<FtpRequestEventArgs>(ftpserver2_ClientRequest);
                ftpserver1.TransferProgress += new EventHandler<TransferProgressEventArgs>(ftpserver2_TransferProgress);
                ftpserver1.TransferComplete += new EventHandler<TransferCompleteEventArgs>(ftpserver2_TransferComplete);
            }
            if (!ftpserver1.IsConnected)
            {
                Run r = new Run("Server1 Status:    Resolving address of " + txtftpserver.Text + "\n" + "Server1 Status:    Connection established, waiting for welcome message... \n");
                r.Foreground = System.Windows.Media.Brushes.Black;
                msg.Inlines.Add(r);
                msgscroll.ScrollToBottom();                   
                ftpserver2_OpenAsyncCompleted(ftpserver1, txtusername.Text, txtpassword.Password);
            }
        }
        catch { }
}
private void Window\u已加载(对象发送方,路由目标)
{
BackgroundWorker工人=新的BackgroundWorker();
worker.DoWork+=委托(对象s、doworkerEventArgs参数)
{
调用(新操作(()=>ConnectFtp());
};
worker.RunWorkerAsync();
}
私有void ConnectFtp()
{
尝试
{
int-port=string.IsNullOrEmpty(txtport.Text)?21:Convert.ToInt32(txtport.Text);
if(ftpserver1==null)
{
ftpserver1=新的FtpClient(txtftpserver.Text,端口);
ftpserver1.ServerResponse+=新事件处理程序(ftpserver2\u ServerResponse);
ftpserver1.ClientRequest+=新事件处理程序(ftpserver2_ClientRequest);
ftpserver1.TransferProgress+=新事件处理程序(ftpserver2_TransferProgress);
ftpserver1.TransferComplete+=新事件处理程序(ftpserver2_TransferComplete);
}
如果(!ftpserver1.IsConnected)
{
Run r=new Run(“Server1状态:解析“+txtftpserver.Text+”\n“+”Server1状态:连接已建立,正在等待欢迎消息…\n”);
r、 前台=System.Windows.Media.brusks.Black;
msg.Inlines.Add(r);
msgscroll.ScrollToBottom();
ftpserver2_OpenAsyncCompleted(ftpserver1,txtusername.Text,txtpassword.Password);
}
}
捕获{}
}
在ConnectFtp()方法中,我连接到ftp服务器。ftp服务器的连接状态为“正在连接”时,UI不工作。但在完成连接后,一切都很好! 请帮帮我!
提前谢谢

您正在为
ConnectFTP
方法调用worker内的UI线程。你需要有这个

BackgroundWorker _worker = new BackgroundWorker();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _worker.DoWork += delegate(object s, DoWorkEventArgs args)
    {
        ConnectFtp();
    };
    _worker.RunWorkerAsync();
}

private void ConnectFtp()
{
 //here i'm connecting to a ftp server. 
}

您正在为
ConnectFTP
方法调用worker中的UI线程。你需要有这个

BackgroundWorker _worker = new BackgroundWorker();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _worker.DoWork += delegate(object s, DoWorkEventArgs args)
    {
        ConnectFtp();
    };
    _worker.RunWorkerAsync();
}

private void ConnectFtp()
{
 //here i'm connecting to a ftp server. 
}

您正在将完整的方法从后台工作线程转储到UI线程。 这里

我认为最好利用.NET4.0中可用的Api,该Api在多核系统上运行良好,即真正的并行线程。使用TPL的优点是,它在变量和UI元素上使用闭包,因此您可以访问不同线程上的值,如果有时不起作用,则在任务开始之前创建局部变量,并在操作方法体中使用它,并使用Dispatcher调用更新UI控件

例如:

using System.Threading;
using System.Threading.Tasks;

private void Window_Loaded(object sender, RoutedEventArgs e)
{
        Task TWorkOnFTP = new TaskFactory().StartNew(ConnectFtp);
}

private void ConnectFtp()
{
     // Here i'm connecting to a ftp server. 
     // Do some I/O operation
     // Now time to update UI controls so we invoke on Dispatcher UI thread
     Dispatcher.Invoke(new Action(() =>
     {
         lblMessage.Text = "Process finished";
         // Some other UI updates..
     }));
}
其他相关参考资料:

  • :
使现代化 根据更新的问题,TPL可按如下方式使用:

    //Closures
    var strPort = txtport.Text;
    var strFTPServer = txtftpserver.Text;
    var strUserName = txtusername.Text;
    var strPassword = txtpassword.Password;

    //Start Task thread
    Task TProcessFTP = new TaskFactory().StartNew(new Action(() =>
    {
        try
        {
            int port = string.IsNullOrEmpty(strPort) ? 21 : Convert.ToInt32(strPort);
            if (ftpserver1 == null)
            {
                ftpserver1 = new FtpClient(strFTPServer, port);
                ftpserver1.ServerResponse += new EventHandler<FtpResponseEventArgs>(ftpserver2_ServerResponse);
                ftpserver1.ClientRequest += new EventHandler<FtpRequestEventArgs>(ftpserver2_ClientRequest);
                ftpserver1.TransferProgress += new EventHandler<TransferProgressEventArgs>(ftpserver2_TransferProgress);
                ftpserver1.TransferComplete += new EventHandler<TransferCompleteEventArgs>(ftpserver2_TransferComplete);
            }
            if (!ftpserver1.IsConnected)
            {
                //Update UI Controls
                Dispatcher.Invoke(new Action(() =>
                {
                    Run r = new Run("Server1 Status:    Resolving address of " + txtftpserver.Text + "\n" + "Server1 Status:    Connection established, waiting for welcome message... \n");
                    r.Foreground = System.Windows.Media.Brushes.Black;
                    msg.Inlines.Add(r);
                    msgscroll.ScrollToBottom();
                    ftpserver2_OpenAsyncCompleted(ftpserver1, strUserName, strPassword);
                }));
            }
        }
        catch { }
    }));
//闭包
var strPort=txtport.Text;
var strFTPServer=txtftpserver.Text;
var strUserName=txtusername.Text;
var strPassword=txtpassword.Password;
//启动任务线程
Task TProcessFTP=new TaskFactory().StartNew(新操作(()=>
{
尝试
{
int-port=string.IsNullOrEmpty(strPort)?21:Convert.ToInt32(strPort);
if(ftpserver1==null)
{
ftpserver1=新的FtpClient(strFTPServer,端口);
ftpserver1.ServerResponse+=新事件处理程序(ftpserver2\u ServerResponse);
ftpserver1.ClientRequest+=新事件处理程序(ftpserver2_ClientRequest);
ftpserver1.TransferProgress+=新事件处理程序(ftpserver2_TransferProgress);
ftpserver1.TransferComplete+=新事件处理程序(ftpserver2_TransferComplete);
}
如果(!ftpserver1.IsConnected)
{
//更新UI控件
Dispatcher.Invoke(新操作(()=>
{
Run r=new Run(“Server1状态:解析“+txtftpserver.Text+”\n“+”Server1状态:连接已建立,正在等待欢迎消息…\n”);
r、 前台=System.Windows.Media.brusks.Black;
msg.Inlines.Add(r);
msgscroll.ScrollToBottom();
ftpserver2_OpenAsyncCompleted(ftpserver1,strUserName,strPassword);
}));
}
}
捕获{}
}));

您正在将完整的方法从后台工作线程转储到UI线程。 这里

我认为最好利用.NET4.0中可用的Api,该Api在多核系统上运行良好,即真正的并行线程。使用TPL的优点是,它在变量和UI元素上使用闭包,因此您可以访问不同线程上的值,如果有时不起作用,则在任务开始之前创建局部变量,并在操作方法体中使用它,并使用Dispatcher调用更新UI控件

例如:

using System.Threading;
using System.Threading.Tasks;

private void Window_Loaded(object sender, RoutedEventArgs e)
{
        Task TWorkOnFTP = new TaskFactory().StartNew(ConnectFtp);
}

private void ConnectFtp()
{
     // Here i'm connecting to a ftp server. 
     // Do some I/O operation
     // Now time to update UI controls so we invoke on Dispatcher UI thread
     Dispatcher.Invoke(new Action(() =>
     {
         lblMessage.Text = "Process finished";
         // Some other UI updates..
     }));
}
其他相关参考资料:

  • :
使现代化 根据更新的问题,TPL可按如下方式使用:

    //Closures
    var strPort = txtport.Text;
    var strFTPServer = txtftpserver.Text;
    var strUserName = txtusername.Text;
    var strPassword = txtpassword.Password;

    //Start Task thread
    Task TProcessFTP = new TaskFactory().StartNew(new Action(() =>
    {
        try
        {
            int port = string.IsNullOrEmpty(strPort) ? 21 : Convert.ToInt32(strPort);
            if (ftpserver1 == null)
            {
                ftpserver1 = new FtpClient(strFTPServer, port);
                ftpserver1.ServerResponse += new EventHandler<FtpResponseEventArgs>(ftpserver2_ServerResponse);
                ftpserver1.ClientRequest += new EventHandler<FtpRequestEventArgs>(ftpserver2_ClientRequest);
                ftpserver1.TransferProgress += new EventHandler<TransferProgressEventArgs>(ftpserver2_TransferProgress);
                ftpserver1.TransferComplete += new EventHandler<TransferCompleteEventArgs>(ftpserver2_TransferComplete);
            }
            if (!ftpserver1.IsConnected)
            {
                //Update UI Controls
                Dispatcher.Invoke(new Action(() =>
                {
                    Run r = new Run("Server1 Status:    Resolving address of " + txtftpserver.Text + "\n" + "Server1 Status:    Connection established, waiting for welcome message... \n");
                    r.Foreground = System.Windows.Media.Brushes.Black;
                    msg.Inlines.Add(r);
                    msgscroll.ScrollToBottom();
                    ftpserver2_OpenAsyncCompleted(ftpserver1, strUserName, strPassword);
                }));
            }
        }
        catch { }
    }));
//闭包
var strPort=txtport.Text;
var strFTPServer=txtftpserver.Text;
var strUserName=txtusername.Text;
var strPassword=txtpassword.Password;
//启动任务线程
Task TProcessFTP=new TaskFactory().StartNew(新操作(()=>
{
尝试
{
int-port=string.IsNullOrEmpty(strPort)?21:Convert.ToInt32(strPort);
if(ftpserver1==null)
{
ftpserver1=新的FtpClient(strFTPServer,端口);
ftpserver1.ServerResponse+=新事件处理程序(ftpserver2\u ServerResponse);
ftpserver1.ClientRequest+=新事件处理程序(ftpserver2_ClientRequest);
ftpserver1.TransferProgress+=新事件处理程序(ftpserver2_TransferProgress);
ftpserver1.TransferComplete+