2016-09-09 71 views
0

我使用遠程雲服務器來存儲我的圖像。如果我使用控制檯執行這些代碼,它運行良好,但在asp.net mvc中它始終掛在在 「的WaitOne()ManualResetEvent.WaitOne始終掛在ASP.NET MVC

public class UploadUtil 
{ 

    public static string UploadBase64(string bucket,string filelocation) 
    { 
     //qiniu.Config.ACCESS_KEY = System.Configuration.ConfigurationManager.AppSettings["ACCESS_KEY"]; 
     //qiniu.Config.SECRET_KEY = System.Configuration.ConfigurationManager.AppSettings["SECRET_KEY"]; 
     qiniu.Config.InitFromAppConfig(); 

     string qiniuKey = Guid.NewGuid().ToString(); 
     string returnUrl = string.Empty; 

     ManualResetEvent done = new ManualResetEvent(false); 
     jpegToBase64 jpeg = new jpegToBase64(filelocation); 
     QiniuFile qfile = new QiniuFile(bucket, qiniuKey); 
     qfile.UploadCompleted += (sender, e) => { 
      returnUrl = e.RawString; 
      Console.Write(e.RawString); 
      done.Set(); 

     }; 
     qfile.UploadFailed += (sender, e) => { 
      QiniuWebException qe = (QiniuWebException)e.Error; 
      Console.WriteLine(qe.Error.ToString()); 
     }; 
     qfile.UploadString((int)jpeg.Filesize, "image/png", jpeg.Base64Content); 
     done.WaitOne(); 
     return returnUrl; 

    } 

} 

的ActionResult的是這樣的,如果我用正常的ActionResult,該錯誤會occurd,所以我必須使用任務

public Task<ActionResult> TestUpload() 
    { 
     var s = UploadUtil.UploadBase64("kmsfan", @"D:\\b.jpg"); 
     return null; 

    } 
+1

阻塞代碼對Web服務器沒有的地方,會導致相當迅速擴展問題。使用異步並使用TaskCompletionSource代替MRE並等待其Task任務將在這裏更好。 – spender

+0

@spender嗨,你能告訴我代碼嗎?因爲我不熟悉你的解釋。 – MapleStory

+0

您正在阻止同步上下文,從而導致死鎖,使用MVC調用「異步等待」,這將不會導致死鎖 –

回答

4

你的ManualResetEvent將永遠不會如果上傳失敗,則發送信號。您應該避免在服務器環境中阻塞同步代碼。

使用TaskCompletionSource來代表你的異步上傳任務:

public class UploadUtil 
{ 

    public static Task<string> UploadBase64Async(string bucket,string filelocation) 
    { 
     var tcs = new TaskCompletionSource<string>(); 
     qiniu.Config.InitFromAppConfig(); 

     string qiniuKey = Guid.NewGuid().ToString(); 

     jpegToBase64 jpeg = new jpegToBase64(filelocation); 
     QiniuFile qfile = new QiniuFile(bucket, qiniuKey); 
     qfile.UploadCompleted += (sender, e) => { 
      var returnUrl = e.RawString; 
      Console.Write(returnUrl); 
      tcs.SetResult(returnUrl);  
     }; 
     qfile.UploadFailed += (sender, e) => { 
      QiniuWebException qe = (QiniuWebException)e.Error; 
      Console.WriteLine(qe.Error.ToString()); 
      tcs.SetException(qe); 
     }; 
     qfile.UploadString((int)jpeg.Filesize, "image/png", jpeg.Base64Content); 
     return tcs.Task;  
    } 

} 

控制器:

public async Task<string> TestUpload() 
{ 
    var s = await UploadUtil.UploadBase64Async("kmsfan", @"D:\\b.jpg"); 
    return s; 
} 
+0

謝謝!它的工作原理!非常感謝。 – MapleStory

+0

難道你沒有異步版本的'UploadCompleted'事件,這將使它更容易實現 –

+0

@Guillaume從.Net 4.5開始並不會有'Task.FromResult',比TaskCompletionSource更好的選項 –