单击“发送”按钮后,我的窗口冻结。它发送文件,然后它应该发布GUI,但它不会。看我的代码:
private void btn_send_Click(object sender, RoutedEventArgs e)
{
if (SBox.UploadFile("user", "service", 1, path.Text))
MessageBox.Show("Success");
else
MessageBox.Show("Fail, try again");
}
那么来自Sbox类的代码:
public static bool UploadFile(string user, string service, int orderId, string filepath)
{
DateTime now = DateTime.Now;
dbx = new DropboxClient(login_key);
string path = "/Files/" + user + "/" + service + "/order - " + orderId + "/received";
string fileName = now.Year + "" + now.ToString("MM") + "" + now.ToString("dd") + "" + Path.GetExtension(filepath);
Task upl = Upload(dbx, path, fileName, File.ReadAllBytes(filepath)); //send file
upl.Wait();
return true;
}
和任务代码:
static async Task Upload(DropboxClient dbx, string folder, string file, byte[] content)
{
using (var mem = new MemoryStream(content))
{
var updated = await dbx.Files.UploadAsync(
folder + "/" + file,
WriteMode.Overwrite.Instance,
body: mem);
Console.WriteLine("Saved {0}/{1} rev {2}", folder, file, updated.Rev);
}
}
正如我所说,文件发送到正确的文件夹但GUI冻结。控制台应用程序完美运行,成功时编写输出。
你正在使用Task.Wait()和upl.Wait();
这会导致当前线程运行并等待任务完成后再继续。
编辑:
如果你想做的不仅仅是那个方法(在完成时执行其他操作),我总是使用Task.Run()
这样的任务:
Task.Run(() =>
{
Upload(...);
OnCompletion();
}
如果你想做UI的东西,记得在调度线程上调用它:
Task.Run(() =>
{
Upload(...);
Dispatcher.BeginInvoke(new Action(() => {
OnCompletion();
};
}
我确实玩了一下并做了一些研究。这是我最后的工作代码Button:
private async void btn_send_Click(object sender, RoutedEventArgs e)
{
SBox sbox = new SBox();
progress.Text = "Uploading file, please wait...";
bool t = await sbox.UploadFromGUI("user", "service", 1, path.Text);
progress.Text = "";
if (t == true)
MessageBox.Show("Success!", "Info", MessageBoxButton.OK, MessageBoxImage.Information);
else
MessageBox.Show("Failed", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
和SBox类中的方法:
public async Task<bool> UploadFromGUI(string user, string service, int orderId, string filepath)
{
DateTime now = DateTime.Now;
dbx = new DropboxClient(login_key);
string path = "/files/" + user + "/" + service + "/order - " + orderId + "/received";
string fileName = now.Year + "" + now.ToString("MM") + "" + now.ToString("dd") + "" + Path.GetExtension(filepath);
try
{
using (var mem = new MemoryStream(File.ReadAllBytes(filepath)))
{
var updated = await dbx.Files.UploadAsync(
path + "/" + fileName,
WriteMode.Overwrite.Instance,
body: mem);
return true;
}
}
catch
{
return false;
}
}