3

HttpFileCollectionBaseHTTP POST でa を受け入れる ASP.NET MVC 3 アクション メソッドがあります。

この方法では、画像のサイズを変更して 3 回アップロードする必要があります。

現在、アクション メソッドは次のようになっています。

public ActionResult ChangeProfilePicture()
{
   var fileUpload = Request.Files[0];

   ResizeAndUpload(fileUpload.InputStream, Size.Original);
   ResizeAndUpload(fileUpload.InputStream, Size.Profile);
   ResizeAndUpload(fileUpload.InputStream, Size.Thumb);

   return Content("Success", "text/plain");   
}

基本的に、これはユーザー プロフィール ページで、プロフィール写真を変更します。アップロードは jQuery AJAX 経由で行われます。

ResizeAndUploadでは、3 つの呼び出しを非同期タスクとして起動し、3 つのタスクがすべて完了するまでアクションの結果を返さないにはどうすればよいでしょうか?

以前はTask.Factory.StartNew非同期タスクを起動するために使用していましたが、それは結果を待つことを気にしなかったときでした。

何か案は?

4

6 に答える 6

7

それを行う簡単な方法の1つは、Joinを使用することです。

public ActionResult ChangeProfilePicture()
{
   var fileUpload = Request.Files[0];
   var threads = new Thread[3];
   threads[0] = new Thread(()=>ResizeAndUpload(fileUpload.InputStream, Size.Original));
   threads[1] = new Thread(()=>ResizeAndUpload(fileUpload.InputStream, Size.Profile));
   threads[2] = new Thread(()=>ResizeAndUpload(fileUpload.InputStream, Size.Thumb));

   threads[0].Start();
   threads[1].Start();
   threads[2].Start();

   threads[0].Join();
   threads[1].Join();
   threads[2].Join();

   return Content("Success", "text/plain");   
}

ResizeAndUploadメソッドがどこかでブロックしている可能性があります(コードを見ないと確実にわかりません)。その場合は、それらをリファクタリングして非同期にすることも価値があります。

于 2011-06-01T00:21:45.143 に答える
6

Task.Factory.StartNew@BFreeの回答と同様に、を使用して動作させることもできました:

public ActionResult ChangeProfilePicture()
{
   var fileUpload = Request.Files[0];
   var threads = new Task[3];
   threads[0] = Task.Factory.StartNew(()=>ResizeAndUpload(fileUpload.InputStream, Size.Original));
   threads[1] = Task.Factory.StartNew(()=>ResizeAndUpload(fileUpload.InputStream, Size.Profile));
   threads[2] = Task.Factory.StartNew(()=>ResizeAndUpload(fileUpload.InputStream, Size.Thumb));

   Task.WaitAll(threads, 120000); // wait for 2mins.

   return Content("Success", "text/plain");   
}

Threadまたはの方が良いかどうかを確認してTaskください。

于 2011-06-01T00:32:21.783 に答える
1

TaskとManualResetEventを使用する別の実装

public ActionResult Sample()
    {
        var wh1 = new ManualResetEvent(false);
        var wh2 = new ManualResetEvent(false);
        var wh3 = new ManualResetEvent(false);

        Task.Factory.StartNew(new Action<object>(wh =>
        {
            // DoSomething();
            var handle = (ManualResetEvent)wh;
            handle.Set();
        }), wh1);

        Task.Factory.StartNew(new Action<object>(wh =>
        {
            // DoSomething();
            var handle = (ManualResetEvent)wh;
            handle.Set();
        }), wh2);

        Task.Factory.StartNew(new Action<object>(wh =>
        {
            // DoSomething();
            var handle = (ManualResetEvent)wh;
            handle.Set();
        }), wh3);

        WaitHandle.WaitAll(new[] { wh1, wh2, wh3 });

        return View();
    }

お役に立てれば。

于 2011-06-01T01:10:02.577 に答える
1

これが私の見解です。待機には便利な「Task.WaitAll」静的メソッドを使用してください..

public MyViewModel LoadData()
{
    MyViewModel viewModel = null;

    try
    {
        Task.Factory.StartNew(() =>
           {
               var task1 = Task<MyViewModel>.Factory.StartNew(() =>
               {
                   return BuildMyViewModel(args);
               });

               var task2 = Task<ViewModel2>.Factory.StartNew(() =>
               {
                   return BuildViewModel2(args);
               });

               var task3 = Task<ViewModel3>.Factory.StartNew(() =>
               {
                   return BuildViewModel3(args);
               });

               Task.WaitAll(task1, task2, task3);

               viewModel = task1.Result;

               viewModel.ViewModel2 = task2.Result;
               viewModel.ViewModel3 = task3.Result;

           }).Wait();
    }
    catch (AggregateException ex)
    {
        System.Diagnostics.Trace.WriteLine(ex.StackTrace); 
        // ...
    }

    return viewModel;
}
于 2012-02-15T00:30:17.777 に答える
0

MVC アクションの非同期パターンもあります。次のリンクを参照してください。

http://msdn.microsoft.com/en-us/library/ee728598.aspx

タスクを引き続き使用できますが、アクションを非同期で実行できるようにするための特別な処理は必要ありません

于 2011-06-01T00:39:43.577 に答える