C# Windows Phone ScheduleAgent在设置时间段抓取图像
我正试图遵循一个,调整它一点,以满足我的需要。我试图每X秒抓取一张新图片(30秒用于调试),并将其设置为新的锁屏背景。我创建了一个ScheduleAgent对象来调用它,但是,它似乎跳过了一个函数。在运行完全相同的函数的C# Windows Phone ScheduleAgent在设置时间段抓取图像,c#,windows-phone-8,C#,Windows Phone 8,我正试图遵循一个,调整它一点,以满足我的需要。我试图每X秒抓取一张新图片(30秒用于调试),并将其设置为新的锁屏背景。我创建了一个ScheduleAgent对象来调用它,但是,它似乎跳过了一个函数。在运行完全相同的函数的MainPage.xaml.cs中,它不会跳过此操作 ScheduleAgent.cs static ScheduledAgent() { ....<irrelevant code>.... protected over
MainPage.xaml.cs
中,它不会跳过此操作
ScheduleAgent.cs
static ScheduledAgent()
{
....<irrelevant code>....
protected override void OnInvoke(ScheduledTask task)
{
.... < Code went here that shouldn't matter > ....
}
Debug.WriteLine("Imagename = " + imageName);
DownloadImagefromServer("https://s3-us-west-2.amazonaws.com/qoutescreen/0" + imageName + ".jpg");
我建议使用“”关键字。这将导致代码暂停并等待操作完成,而无需担心互斥锁或其他线程阻塞策略 不幸的是,Windows Phone缺少WebClient上的非异步方法,因此有一点设置,显然是从中窃取的 要将async与WebClient一起使用,请安装NuGet软件包,然后可以使用OpenReadTaskAsync
因此,执行过程会等待“OpenRead”调用完成,然后再处理结果,然后返回控制。问题在于
DownloadImagefromServer
是异步的,因此该方法会在图像下载之前返回。然后调用NotifyComplete
,这将停止后台代理的执行。在文件下载完成之前,使用互斥锁防止OnInvoke
方法返回。但它会完全跳过函数调用。所以对我来说,似乎它甚至没有尝试,并不是说它没有足够的时间。我的假设是错误的吗?当然,设置一个断点,但我不明白为什么它会跳过调用我就是这么做的。我在所有地方设置了断点,它似乎只是跳过了它。该函数从未被命中,我也不知道为什么。@JcKelley在计划代理中实例化新的BitmapImage对象时遇到了一些问题。当我调用构造函数时,它总是抛出异常。我试图将来自OnInvoke()方法的所有代码放入Deployment.Current.Dispatcher.BeginInvoke()调用中,但随后所有WeClient下载都停止工作。您是否遇到过类似的问题?它无法将OpenRead
识别为webClient对象的有效方法?你认为这是一个单独的问题还是相关的?哦,你是对的。Windows Phone只有异步方法。我已经编辑了答案。等待应该仍然阻止线程,直到打开完成。似乎它仍然没有咬。“不能等待无效”,我需要返回任务对象吗?啊,是的,你需要。对所有的错误感到抱歉。我没有在Visual Studio中使用我的计算机,因此无法编译。我尝试了这一点,但似乎遇到了相同的错误。有什么想法吗?
// If debugging is enabled, launch the agent again in one minute.
// debug, so run in every 30 secs
#if(DEBUG_AGENT)
ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(30));
System.Diagnostics.Debug.WriteLine("Periodic task is started again: " + task.Name);
#endif
// Call NotifyComplete to let the system know the agent is done working.
NotifyComplete();
}
//===============================================================================
private async void LockScreenChange(string filePathOfTheImage, bool isAppResource)
{
if (!LockScreenManager.IsProvidedByCurrentApplication)
{
// If you're not the provider, this call will prompt the user for permission.
// Calling RequestAccessAsync from a background agent is not allowed.
await LockScreenManager.RequestAccessAsync();
}
// Only do further work if the access is granted.
if (LockScreenManager.IsProvidedByCurrentApplication)
{
// At this stage, the app is the active lock screen background provider.
// The following code example shows the new URI schema.
// ms-appdata points to the root of the local app data folder.
// ms-appx points to the Local app install folder, to reference resources bundled in the XAP package
var schema = isAppResource ? "ms-appx:///" : "ms-appdata:///Local/";
var uri = new Uri(schema + filePathOfTheImage, UriKind.Absolute);
// Set the lock screen background image.
LockScreen.SetImageUri(uri);
// Get the URI of the lock screen background image.
var currentImage = LockScreen.GetImageUri();
System.Diagnostics.Debug.WriteLine("The new lock screen background image is set to {0}", currentImage.ToString());
}
}
private async Task DownloadImagefromServer(string imgUrl)
{
Debug.WriteLine("Attempting to Get Image from Server...");
WebClient client = new WebClient();
try
{
// I GET A "Cannot await Void" problem here?!?!?
//=================================================================
var result = await client.OpenReadAsync(new Uri(imgUrl, UriKind.Absolute));
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(result);
return result;
}
catch (Exception e)
{
Debug.WriteLine(e);
}
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
//client.OpenReadAsync(new Uri(imgUrl, UriKind.Absolute));
}
//------------------------------------------------------------------
//THIS FUNCTION IS NEVER HIT WHEN RUN IN THE ScheduleAgent.cs CODE, HOWEVER
// WHEN IT IS RUN INT HE MainPage.xaml.cs CODE (Which is a copy/paste) IT RUNS FINE
// WHY IS IT NOT HITTING THIS? HOW CAN I FIX IT?
//------------------------------------------------------------------
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(e.Result);
//img.Source = bitmap;
// Create a filename for JPEG file in isolated storage.
String tempJPEG = "DownloadedWalleper.jpg";
// Create virtual store and file stream. Check for duplicate tempJPEG files.
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (myIsolatedStorage.FileExists(tempJPEG))
{
myIsolatedStorage.DeleteFile(tempJPEG);
}
IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(tempJPEG);
StreamResourceInfo sri = null;
Uri uri = new Uri(tempJPEG, UriKind.Relative);
sri = Application.GetResourceStream(uri);
//BitmapImage bitmap = new BitmapImage();
//bitmap.SetSource(sri.Stream);
WriteableBitmap wb = new WriteableBitmap(bitmap);
// Encode WriteableBitmap object to a JPEG stream.
Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
//wb.SaveJpeg(fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
fileStream.Close();
}
LockScreenChange("DownloadedWalleper.jpg", false);
}
}
private async void DownloadImagefromServer(string imgUrl)
{
Debug.WriteLine("Attempting to Get Image from Server...");
WebClient client = new WebClient();
var result = await client.OpenReadTaskAsync(new Uri(imgUrl, UriKind.Absolute));
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(result);
//img.Source = bitmap;
... rest of your code from OpenReadCompleted goes here
}