2016-09-09 108 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更好的选项 –