MapleStory MapleStory - 2 months ago 53
ASP.NET (C#) Question

ManualResetEvent.WaitOne is always hanging in ASP.NET MVC

I used the remote cloud server to store my images.If I use the console to execute these code ,it works well ,but in asp.net mvc it is always hanging on the "WaitOne()"

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;

}

}


the actionresult looks like this,if I use the normal ActionResult ,the error would occurd ,so I have to use Task

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

}

Answer

Your ManualResetEvent will never be signaled if the upload fails. You should avoid blocking synchronization code in a server environment.

Use a TaskCompletionSource to represent your asynchronous upload task :

public class UploadUtil
{

    public static Task<string> UploadBase64Async(string bucket,string filelocation)
    {
       var tcs = new TaskCompletionSource();
       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;
}
Comments