我無法在Silverlight中聲明任何特定的文件處理知識,但這裏是我用於WPF應用程序中工作線程的長任務的模式。它似乎在一個快速測試Silverlight項目中工作正常。
我會避免嘗試在線程之間傳遞流。相反,計算您的後臺任務所需的一組參數,並創建一個對象以將它們傳遞給您的線程。讓後臺線程打開文件。所以,如果你需要的文件夾搜索文件壓縮並輸出位置把壓縮到,你可能聲明:
class TaskStartupInfo
{
public string SourceFolder { get; set; }
public string TargetFile { get; set; }
}
然後您可以創建這個類的一個實例,並把它傳遞到你的背景任務:
private void startTaskButton_Click(object sender, RoutedEventArgs e)
{
TaskStartupInfo tsi = new TaskStartupInfo()
{
SourceFolder = @"C:\Some\Folder\",
TargetFile = @"C:\AnotherFolder\data.zip"
};
ThreadPool.QueueUserWorkItem(o => longRunningProcess(tsi));
}
在你的情況,路徑可以來自你的主UI線程上運行SaveFileDialog - 因爲該線程將不會運行大部分工作被捆綁起來。然後,您longRunningProcess()
方法可以採取的數據,並使用它:
private void longRunningProcess(object o)
{
TaskStartupInfo tsi = o as TaskStartupInfo;
int taskLength = calculateTaskLength()
// open any files required
this.Dispatcher.BeginInvoke(() => { progressBar1.Value = 0; progressBar1.Maximum = taskLength; });
for (int i = 0; i < taskLength; i++)
{
doSomethingSlow();
this.Dispatcher.BeginInvoke(() => progressBar1.Value += 1);
}
// close/dispose files
}
注意如何任何企圖訪問UI對象(progressBar1
在這種情況下)是通過使用分派對象運行的委託完成的。此調度程序處理確保UI對象僅由UI線程更新的問題。這應該確保在任務的每個片段完成後更新進度欄。
編輯:基於業務方案的意見,並且已經做了一些進一步深挖,我看到Silverlight的安全沙箱中規定未在桌面WPF應用程序強加文件訪問限制。
寫入獨立存儲之外的文件系統確實需要Silverlight應用程序運行時纔會提升。這可以配置爲項目屬性的一部分 - 在屬性的Silverlight選項卡上有一個「啓用瀏覽器不運行」複選框,一旦啓用了下面的「瀏覽器設置不足」按鈕,它允許您打開一個進一步的選項對話框具有「在瀏覽器外運行時需要提高信任」複選框。我沒有對它進行測試,但是這個選項聽起來好像不會在瀏覽器中獲得提升的信任 - 所以檢查代碼中的安全錯誤並處理較低的信任情況(如果發生的話)可能是有意義的。
啓用該設置後,您似乎可以使用普通流訪問用戶庫中的文件,但不能訪問文件系統中的其他文件。默認情況下,OpenFileDialog
和SaveFileDialog
類會返回問題中隱含的流,但如果您願意,它們都允許您訪問文件名而不是流。當打開一個文件的文件名是
myOpenFileDialog.File.FullName
下隱藏和保存你似乎能夠使用
mySaveFileDialog.SafeFileName
代替。
所以下面的代碼可以在升高外的瀏覽器應用程序的工作:
private void start_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
if (sfd.ShowDialog() != true)
{
return;
}
TaskStartupInfo tsi = new TaskStartupInfo()
{
SourceFolder = @"C:\Users\MyUser\Documents\Information",
TargetFile = sfd.SafeFileName
};
ThreadPool.QueueUserWorkItem(o => longRunningProcess(tsi));
}
private void longRunningProcess(object o)
{
TaskStartupInfo tsi = o as TaskStartupInfo;
var files = Directory.EnumerateFiles(tsi.SourceFolder);
int taskLength = files.Count();
this.Dispatcher.BeginInvoke(() => { progressBar1.Value = 0; progressBar1.Maximum = taskLength; });
using (StreamWriter fs = new StreamWriter(tsi.TargetFile))
{
foreach(string file in files)
{
fs.WriteLine(file);
doSomethingSlow();
this.Dispatcher.BeginInvoke(() => progressBar1.Value += 1);
}
}
}
而且,讓你倆的文件訪問,並在backgrond文件的處理正確地更新進度條。
我想我將不得不考慮使用提升權限運行SL應用程序。問題是SL'SaveFileDialog'沒有提供我可以訪問的路徑,只有用戶指定的流 - 否則我甚至不會使用ZIP(它實際上只是所有圖像的容器)只需將文件直接寫入路徑即可。我相信,如果我提升,我可以不受懲罰地訪問用戶庫文件夾。 –
乾杯 - 我原本避開高架跑步,但在這種情況下,這似乎是愚蠢的。然而,運行提升後,我可以完全取消整個zip文件,只需將圖像直接寫入用戶My Pictures文件夾的文件夾即可。 –