2016-09-09 4 views
0

Ich habe den Remote-Cloud-Server verwendet, um meine Bilder zu speichern. Wenn ich die Konsole diesen Code ausführen, funktioniert es gut, aber in asp.net mvc ist es immer hängen die "WaitOne()"ManualResetEvent.WaitOne hängt immer in 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; 

    } 

} 

die Action sieht wie folgt aus, wenn ich den normalen Action verwenden, wäre der Fehler occurd, so habe ich Task-

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

    } 
+1

Sperrcode keinen Platz auf einem Web-Server hat und führt Probleme ziemlich schnell zu skalieren. Asynchron zu sein und eine TaskCompletionSource anstelle des MRE zu verwenden und auf seine Task zu warten, wäre hier vorzuziehen. – spender

+0

@spender Hallo, kannst du mir den Code zeigen, weil ich deine Erklärung nicht kenne? – MapleStory

+0

Sie blockieren den Synchronisierungskontext, wodurch Deadlock verursacht wird. Verwenden Sie 'Async Await' für MVC-Aufrufe, was nicht zum Deadlock führt. –

Antwort

4

Ihre Manual verwenden wird nie wird signalisiert, wenn der Upload fehlschlägt. Sie sollten den Synchronisierungscode in einer Serverumgebung nicht blockieren.

Verwenden Sie ein TaskCompletionSource Ihre asynchrone Upload Aufgabe darzustellen:

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;  
    } 

} 

Controller:

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

danke, es funktioniert! sehr schätzen. – MapleStory

+0

Haben Sie nicht die Async-Version von 'UploadCompleted' Ereignis, das würde es viel einfacher zu implementieren –

+0

@Guillaume From.Net 4.5 weiter wäre nicht" Task.FromResult ", eine bessere Option als" TaskCompletionSource " –