0

ユーザーがボタンをクリックしたときに「準備完了」と「進行中」を切り替えるラベルだけが必要な状況があります。ラベルは最初は「準備完了」状態です。ユーザーがボタンをクリックすると、ラベルは「進行中」と表示され、ファイルのコピーなど、いくつかのタスクを実行する必要があります。タスクが正常に完了すると、ラベルは再び「準備完了」と表示されます。現在、このコードを使用していますが、ラベルのステータスは変わりません。どうすればこれを機能させることができますか。助けてください。

 private void button1_Click(object sender, EventArgs e)
 {
        status.Text = "In Progress";
        if (listBox1.Items.Count == 0)
        {
            MessageBox.Show("Please select a file to upload");
        }
        FtpClient client = new FtpClient("*******", "*******", "******");
        string fileName = getFileNameFromPath(listBox1.Items[0].ToString());
        string localFile = listBox1.Items[0].ToString();
        string remoteFile = "**********/"+fileName;
        string link = client.upload(remoteFile, localFile);
        listBox1.Items.RemoveAt(0);
        textBox1.Text = link; 
        status.Text = "Ready";  
  }
4

1 に答える 1

2

長時間実行されているプロセス中に UI スレッドをブロックしているため、UI がテキスト値を更新したり、ユーザー入力を受け取ったり、そのために何かをしたりすることができなくなります。

UI スレッドをブロックしないように、実行時間の長い作業を非同期で行う必要があります。

理想的には、あなたが提供する非同期メソッドを持っているでしょうFtpClient(さらに良いことに、それは a を返しますTask)。これにより、次のように書くことができます。

private async void button1_Click(object sender, EventArgs e)
{
    status.Text = "In Progress";
    if (listBox1.Items.Count == 0)
    {
        MessageBox.Show("Please select a file to upload");
    }
    FtpClient client = new FtpClient("*******", "*******", "******");
    string fileName = getFileNameFromPath(listBox1.Items[0].ToString());
    string localFile = listBox1.Items[0].ToString();
    string remoteFile = "**********/" + fileName;
    string link = await client.uploadAsync(remoteFile, localFile);
    listBox1.Items.RemoveAt(0);
    textBox1.Text = link;
    status.Text = "Ready";
}

そして、あなたは終わったでしょう。非同期メソッドが提供されていない場合は、回避策として、新しいタスクを開始してバックグラウンドで作業を行うことができます。

private async void button1_Click(object sender, EventArgs e)
{
    status.Text = "In Progress";
    if (listBox1.Items.Count == 0)
    {
        MessageBox.Show("Please select a file to upload");
    }
    FtpClient client = new FtpClient("*******", "*******", "******");
    string fileName = getFileNameFromPath(listBox1.Items[0].ToString());
    string localFile = listBox1.Items[0].ToString();
    string remoteFile = "**********/" + fileName;
    string link = await Task.Run(() => client.upload(remoteFile, localFile));
    listBox1.Items.RemoveAt(0);
    textBox1.Text = link;
    status.Text = "Ready";
}

使用できる C# 5.0 と .NET 4.5 がない場合はawait、次を使用できますBackgroundWorker

private void button1_Click(object sender, EventArgs e)
{
    status.Text = "In Progress";
    if (listBox1.Items.Count == 0)
    {
        MessageBox.Show("Please select a file to upload");
    }
    string fileName = getFileNameFromPath(listBox1.Items[0].ToString());
    string localFile = listBox1.Items[0].ToString();
    string remoteFile = "**********/" + fileName;
    var worker = new BackgroundWorker();
    worker.DoWork += (s, args) =>
    {
        FtpClient client = new FtpClient("*******", "*******", "******");
        args.Result =  client.upload(remoteFile, localFile);
    };
    worker.RunWorkerCompleted += (s, args) =>
    {
        listBox1.Items.RemoveAt(0);
        textBox1.Text = args.Result as string;
        status.Text = "Ready";
    };
    worker.RunWorkerAsync();
}
于 2013-10-10T20:11:00.593 に答える