1

5分前に面接を受けました。私はこのシナリオを与えられ、C# 1.0 または 2.0 でこれを処理する方法について質問されました。彼は、これを処理するための基本的な機能があると言いましたが、私にはわかりませんでした。誰か助けてください:(

質問:

Winform アプリケーションには 2 つのテキスト ボックスとボタンがあります。1つのテキストボックスが入力値を受け取り、ボタンがクリックされると、サーバーで入力を処理します。これには非常に時間がかかり、最終的に別のテキストボックスに結果が表示されます。サーバーで非常に長い時間がかかるため、UI が中断されるべきではありません。彼が私に尋ねたこのシナリオをどのように処理しますか :(

私が与えた答え:

私はマルチスレッドについて話し、async と await について話しました。彼は、C# 2.0 でこれを処理する簡単な方法を期待していました。私は非同期デリゲートについて推測していました。彼は確信が持てませんでした。誰かが少し理解できるコードで私を説明してください:)

4

2 に答える 2

2

長時間実行されるプロセスを UI とは別のスレッドで実行して、ハングしないようにしBackgroundWorkerます。たとえば、次のように使用されます。

bgWorker.RunWorkerAsync([DATA TO PROCESS])//Passing in data to operate on

private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
      MyObject obj = (MyObject)sender;

      //
      // Do some work with the data on the server
      // 

      // Report on progess, is it done?
      bgWorker.ReportProgress();
}

作業完了メソッドを持つこともできます

 private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
 {
       //Work is complete, notify user
 }

ThreadPoolを使用することもできます。これにはもう少し設定が必要ですが、より柔軟です。例えば: -

ThreadPool.QueueUserWorkItem(new WaitCallback(DoWork), [DATA TO PROCESS]);
Interlocked.Increment(ref workItems);

workItems は、処理が残っているアイテムの数です。これは、タスクが完了したかどうかを追跡するために使用できます。DoWork次に、データを処理して workItems カウンターをデクリメントするメソッドを定義します。アイテムが処理されると、次のようなデリゲートを介して進行状況を報告します。

  private delegate void ThreadDone(MyObject obj);
  private delegate void TaskDone();

  public void DoWork(object sender)
   {
        MyObject obj = (MyObject)sender;

        this.Invoke(new ThreadDone(ReportProgress), result);
        Interlocked.Decrement(ref workItems);

        if (workItems == 0)
        {
            this.Invoke(new TaskDone(WorkComplete));
        }
    }

レポートの進行状況は次のようになります。

private void ReportProgress(MyObject obj)
{
    if (workItems >= 0)
    {
        //Job isn't complete, report progress             
    }
}

private void WorkComplete()
{

}
于 2013-03-12T13:07:20.863 に答える
0

In .Net 2 winform applications, the simplest solution is to use a BackgroundWorker. Its events are raised on the UI thread so you don't need to do any marshalling yourself.

The usual pattern looks like:

BackgroundWorker bg = new BackgroundWorker();
bg.DoWork += delegate(object sender, DoWorkEventArgs e) {
    try {
        e.Result = server.LongRunningOperation();
    }
    catch(Exception ex) {
        e.Error = ex;
    }
};

bg.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs e) {
    //update UI
};

bg.RunWorkerAsync();
于 2013-03-12T13:06:47.617 に答える