当当前选项卡忙于处理时,Winforms会在选项卡之间切换

本文关键字:选项 Winforms 之间 处理 于处理 | 更新日期: 2023-09-27 18:09:29

我有winform (c#)与多选项卡,当前聚焦的选项卡忙于做冗长的异步操作和嵌入的progressbasr"在该选项卡"显示进度。我想让用户能够导航到其他选项卡和执行其他任务,以防他/她不想等待。那么我怎样才能简单而稳健地做到这一点呢?

这是一个很长的op:

foreach (DataRow _dr in _allDt.Rows)
{
   //check if machine is online out of 100 machines list using async approach
        if (_connectionUtil.ConnectionIsOn(_dr["ipAddress"].ToString()))
            _onMachineAl.Add(_machineInfo);
    _progressBar.PerformStep();
 }

我必须使用线程吗?或者更简单的方法?请提供代码段或有用的源代码。

编辑:

//async part:
 using (TcpClient tcpClient = new TcpClient())
            {
                IAsyncResult result = tcpClient.BeginConnect(ipAddress, 3306, null, null);
                WaitHandle timeoutHandler = result.AsyncWaitHandle;

谢谢,

当当前选项卡忙于处理时,Winforms会在选项卡之间切换

如果你已经在异步执行任务,那么用户应该已经能够在选项卡之间切换,因为异步操作不会阻塞UI线程。

如果你没有真正异步执行任务,用户将无法做任何事情,因为你阻塞了UI线程。

话虽如此,我怀疑你属于第二阵营,所以像这样的东西应该可以帮助你开始:

var mi = new MethodInvoker(() =>
{
    foreach(dataRow _dr in _allDt.Rows)
    {
        if(_connectionUtil.ConnectionIsOn(_dr["ipAddress"].ToString()))
            _onMachineAl.Add(_machineInfo);
        this._progressBar.Invoke(() => { _progressBar.PerformStep(); });
    }
});
mi.BeginInvoke(null, null);

你需要在单独的线程或后台worker中运行你的'长时间'操作。在这种情况下,用户界面将是免费的,用户可以继续使用应用程序。但是不要忘记在操作完成时通知用户。

示例如下:

new System.Threading.Thread(new System.Threading.ThreadStart(delegate() 
    {
        foreach (DataRow _dr in _allDt.Rows)
        {
            //check if machine is online out of 100 machines list using async approach
            if (_connectionUtil.ConnectionIsOn(_dr["ipAddress"].ToString()))
                _onMachineAl.Add(_machineInfo);
            this._progressBar.Invoke(new MethodInvoker(delegate() // Invoke you need for accessing the UI thread and controls
            { 
                _progressBar.PerformStep();
            }));
        }
    })).Start();