天道酬勤,学无止境

尝试捕获信号量的正确方法(Proper way to try-catch a semaphore)

问题

在 try-catch 块中包装信号量动作的正确方法是什么? 如果获取操作在获取了一定数量(但不是全部)请求的许可后被中断,会发生什么情况? 你怎么知道又要释放多少? 发布是否应该进入“最终”块,但是如果操作被中断,您是否可能不会发布您没有获得的许可?

try {
    lock.acquire(permits);

    //Do some things that require synchronization

    //Make sure to release all of the permits again!
    lock.release(permits);
} catch (InterruptedException e) {
    log.error("Interrupted!");
}
回答1

Semaphore.acquire(int)方法是一个全有或全无操作,要么获得所有请求的许可,要么阻止。 您可以对代码进行双重尝试,或者让(可能)中断的异常从获取中冒泡到您的调用堆栈中。

双重尝试块:

try {
    lock.acquire(permits);

    try {
        // do some stuff here
    } finally {
        lock.release(permits);
    }
} catch(final InterruptedException ie) {
    // handle acquire failure here
}

气泡“获取”异常:

lock.acquire(permits);

try {
    // do some stuff here
} finally {
    lock.release(permits);
}

在切线上,请记住,必须通过严格的编程约定来保持信号量的平衡,因此您应该始终发布尽可能多的许可。

回答2

BoundedHashSet add方法为例,

    public boolean add(T o) throws InterruptedException {
        sem.acquire();
        boolean wasAdded = false;
        try {
            wasAdded = set.add(o);
            return wasAdded;
        } finally {
            if (!wasAdded)
                sem.release();
        }
    }

如果sem.acquire(); 抛出 InterruptedException,跳过 try 块和 finally 块。

否则,我们成功获取信号量,try块和finally块将一起执行。 也就是说,我们将发布与我们获得的相同数量的许可证。

回答3

要添加@Perception 的答案,您可以选择分离嵌套的双重 try-catch 并在获取块上添加重试,这适合我的用例。

int retry_limit = 10;
boolean acquired = lock.tryAcquire(permits);
for (int i=0; i < retry_limit && !acquired; ++i) {
    try {
        Thread.sleep(1000);
    }
    acquired = lock.tryAcquire(permits);
}
if (!acquired) {
    throw new IllegalStateException("Unable to acquire permits");
}
try {
    // do some stuff here
} catch(InterruptedException ie) {
    // handle acquire failure here
} catch(Exception ex) {
    // handle other exceptions here
} finally {
    lock.release(permits);
}

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • C ++中的捕获分段错误(Catch Segmentation fault in c++)
    问题 try-catch块会捕获分段错误吗? 我正在使用下面提供的功能读取文本文件,但有时该文件为空并且程序崩溃。 我希望程序继续运行,并在此文件为空或正在使用时提供另一个文件。 Path2D read_gesture(const char* filename) { Path2D path; //MultiStrokeGesture MultiStrokes; vector<string> text_file; int no_of_paths=0; std::ifstream ifs(filename); for (std::string line; std::getline(ifs, line); ) { no_of_paths=no_of_paths+1; double a, b; stringstream ss(line); if (!(ss >> a >> b)) {cout<<"wrong format"<<endl;} std::cout << "You said, " << a << ", " << b << ".\n"; path.push_back(Point2D(a,b)); } cout<<"saving gesture"<<endl; return path; } 我尝试了类似的东西: Path2D path; try { path=read_gesture
  • iPhone / Objective-C的try-catch异常处理实践(Try-catch exception handling practice for iPhone/Objective-C)
    问题 抱歉,如果这个问题已经在其他地方得到回答,但是在搜索时找不到任何决定性的答案: 我想知道何时在Objective-C iPhone应用程序中使用try-catch块。 苹果公司的“ Objective-C编程语言简介”指出,异常是占用大量资源的,并且“不应将异常用于一般的流控制,或仅用于表示错误”。 通过阅读这里的一些相关问题,我还发现人们在实践中并不经常使用这种方法。 所以我想问题是:在为iPhone / Objective-C开发时,什么时候适合使用try-catch块?什么时候绝对不使用它们? 例如,当使用数组中的对象时,我可以使用它们来捕获边界和其他异常。 我有一个方法,它执行的任务很少,这些对象在多个数组中传递。 如果发生错误,该方法返回nil,并且try-catch块可以帮助我捕获异常。 但是,我当然可以在这里和那里写一些小的if-tests以确保例如,我永远不要尝试访问超出数组范围的索引。 在这个情况下,你会怎么做? 非常感谢! 回答1 仅适合使用@ try / @ catch处理不可恢复的错误。 绝对不适合使用@ throw / @ try / @ catch进行类似控制流的操作。 特别是,除非您的目标是捕获异常并以某种方式报告错误,否则通常不适合用于捕获越界异常,然后(通常)崩溃或至少警告用户您的应用程序处于不一致状态,并且可能会丢失数据。
  • dispatch_semaphore_t 重用 - 我在这里错过了什么?(dispatch_semaphore_t reuse - What am I missing here?)
    问题 我有一些代码,我使用 dispatch_semaphore_t 来表示操作完成。 当信号量是成员变量时,它的行为似乎不正确。 我将展示有效的示例代码和似乎无效的示例: @implementation someClass { dispatch_semaphore_t memberSem; dispatch_semaphore_t* semPtr; NSThread* worker; BOOL taskDone; } - (id)init { // Set up the worker thread and launch it - not shown here. memberSem= dispatch_semaphore_create(0); semPtr= NULL; taskDone= FALSE; } - (void)dealloc { // Clean up the worker thread as needed - not shown here. if((NULL != semPtr) && (NULL != *semPtr)) disptatch_release(*semPtr); dispatch_release(memberSem); } - (void)doSomethingArduous { while([self notDone]) // Does
  • Proper way to try-catch a semaphore
    What is the proper way to wrap semaphore actions in a try-catch block? What happens if the acquire action is interrupted after it has acquired some number, but not all, of the permits requested? How do you know how many to release again? Should the release go in a "finally" block, but then aren't you possibly releasing permits you didn't get if the action was interrupted? try { lock.acquire(permits); //Do some things that require synchronization //Make sure to release all of the permits again! lock.release(permits); } catch (InterruptedException e) { log.error("Interrupted!"); }
  • 什么更好/更快? 尝试捕获或避免异常?(What's better/faster? Try-catch or avoid exception?)
    问题 我想知道,一般编程中什么更好或/更快? 避免异常还是等待异常? 避免例外是: string a = null; list = someMethod(); if(list.Length > 0 ){ a = list[0]; } if(a!=null) ... 或者尝试捕获异常... string a = null; try{ a = someMethod()[0]; catch{} if(a!=null) ... 回答1 性能不是这里最相关的问题。 问题是,两者中的哪一个会导致更具可读性/可维护性/可测试性的程序。 您可以稍后再担心性能问题。 一般情况下,不要使用异常进行流量控制。 它们实际上是一个非本地的goto ,这使得程序更难以阅读和遵循。 因此,它们应保留用于特殊情况。 如果您可以不使用try-catch块进行流量控制,请不要这样做。 您的程序将更具可读性和可维护性。 处理这种情况的“正确”方法是 var list = someMethod(); if(list == null || list.Length == 0) { // handle something bad } string a = list[0]; if(a != null) { // go } 如果存在保证someMethod的返回值不为 null 且不为空的合同 ( Contract.Ensures
  • 带有nextInt的try-catch语句,正确的实现方式?(Try-catch statement inside while with nextInt, correct way to implement?)
    问题 我正在尝试编写最紧凑的解决方案,用于仅使用 nextInt() 方法和它抛出的异常来从用户读取整数以排除错误......这是我现在拥有的代码: Scanner sn = new Scanner(System.in); boolean inputNotNull = true; while (inputNotNull) { try { int number = sn.nextInt(); System.out.printf("The number %d is power of 2: %b\n", number, isPowerOfTwo(number)); if (number == 0) { inputNotNull = false; } } catch(InputMismatchException e) { System.err.println("Wrong input! Input only integer numbers please..."); } } 所以,这应该做的是等待来自用户的整数。 如果用户输入0结束程序。 我的想法是尝试排除用户使用InputMismatchException输入除整数以外的其他内容时的场景(我知道这不是捕获 RuntimeException 的最佳实践)。 当引发异常时,会打印一条错误消息,并且程序返回到 while 循环
  • 为什么我们不必将try-catch添加到RuntimeException?(Why we don't have to add try-catch to a RuntimeException?)
    问题 我想问为什么我们不必将try-catch块添加到RuntimeException而我们应该将其与其他异常一起添加呢? 我的意思是: public class Main { public static void main(String[] args) { throw new RuntimeException(); } } 编辑:当我说: throw new RuntimeException(); 显然会有例外发生,那么为什么编译器不禁止这样做呢? 回答1 那是因为这是一个未经检查的异常。 不需要显式声明或捕获它。 另请参阅有关该主题的Sun教程。 更新:通常,您仅应抛出RuntimeException (最好是javadoc中列出的其子类之一),以表明调用者做错了。 即传递一个null参数(然后抛出NullPointerException)或一个非法参数(然后抛出IllegalArgumentException),或者在错误的时间/状态(然后抛出IllegalStateException)调用该方法,等等。 调用者应该修复其代码以避免这种情况。 例如,预先检查参数是否为null,或者参数的格式/语法是否正确,或确保在正确的时间调用该方法。 如果在特定情况下应该抛出运行时异常,并且您不能使用其特定的子类之一,则应该对它进行扩展
  • 处理(在python中)IOError的正确方法是什么:[Errno 4] Interrupted system call,由multiprocessing.Queue.get引发(What is the proper way to handle (in python) IOError: [Errno 4] Interrupted system call, raised by multiprocessing.Queue.get)
    问题 当我使用 multiprocessing.Queue.get 时,有时会由于 EINTR 而出现异常。 我肯定知道有时会无缘无故地发生这种情况(我在 tmux 缓冲区中打开另一个窗格),在这种情况下,我想继续工作并重试该操作。 我可以想象,在其他一些情况下,错误是由于一个很好的原因,我应该停止运行或修复一些错误。 我如何区分这两者? 提前致谢 回答1 当应用程序在等待其他输入时收到信号时,许多系统调用都会返回EINTR错误。 通常,这些信号可能非常温和并且已经由 Python 处理,但底层系统调用最终仍会被中断。 在进行 C/C++ 编码时,这是您不能完全依赖sleep()等函数的原因之一。 Python 库有时会在内部处理此错误代码,但显然在这种情况下它们不是。 您可能有兴趣阅读讨论此问题的线程。 EINTR的一般方法是简单地处理错误并再次重试操作 - 这应该是使用队列上的get()方法进行的安全操作。 可以使用这样的东西,将队列作为参数传递并替换队列上get()方法的使用: import errno def my_queue_get(queue, block=True, timeout=None): while True: try: return queue.get(block, timeout) except IOError, e: if e.errno !=
  • 为什么以这种方式根据信号量实现监视器?(Why is a monitor implemented in terms of semaphores this way?)
    问题 我无法根据操作系统概念中的信号量来理解监视器的实现 5.8.3 使用信号量实现监视器我们现在考虑使用信号量的监控机制的可能实现。 对于每个监视器,都提供了一个信号量互斥锁(初始化为 1)。 进程在进入监视器前必须执行wait(mutex),离开监视器后必须执行signal(mutex)。 由于信令进程必须等到恢复的进程离开或等待,因此引入了一个额外的信号量next ,初始化为 0。信令进程可以使用next挂起自己。 还提供了一个整数变量next_count来计算next挂起的进程数。 因此,每个外部函数F被替换为wait(mutex); ... body of F ... if (next count > 0) signal(next); else signal(mutex); 确保监视器内的互斥。 我们现在也可以描述条件变量是如何实现的。 对于每个条件x ,我们引入一个信号量x_sem和一个整数变量x_count ,两者都初始化为 0。操作x.wait()现在可以实现为x_count++; if (next_count > 0) signal(next); else signal(mutex); wait(x sem); x_count--; 操作x.signal()可以实现为if (x_count > 0) { next_count++; signal(x_sem)
  • 信号量信号与互斥量(Semaphore signalling vs mutex)
    问题 我正在查看一些描述互斥量和二进制信号量之间区别的主题。 在许多主题中,都说明信号量充当信号量机制,即如果一个线程锁定了一个信号量,则另一个线程可以解锁(释放)该信号量(充当信号量)。 但是在互斥锁的情况下,只有锁定互斥锁的线程才能解锁它。它不能被任何其他线程解锁,如果其他线程试图解锁它,这将返回错误。 我曾尝试编写使用互斥锁进行同步的代码。 在代码中,我在一个线程中锁定了互斥锁,并在另一个线程中成功解锁了互斥锁。 有人可以解释一下这是怎么发生的吗?根据其他线程的答案,其他线程应该无法解锁互斥锁。 任何建议都是最受欢迎的。 回答1 典型的 POSIX 线程实现不执行任何检查或验证解锁互斥锁的线程与锁定该互斥锁的线程相同(或者甚至可能甚至首先锁定互斥锁)。 这不是互斥锁的使用方式。 “互斥”一词的意思是互斥; 该概念的目的是为多个线程提供一种机制,以便在没有其他线程干扰的情况下安全地访问或修改资源(例如数据结构),并且在完成修改后,在解锁互斥锁之前使资源处于一致状态。 在运行时捕获此类编程错误可能很好(就像捕获对数组的越界写入一样),但默认情况下,提供此类簿记和保护在性能方面过于昂贵; 互斥锁和解锁操作应该为您提供最小的开销以使其可用。 这就是您成功从错误线程解锁互斥锁的原因。 在标准的 Linux pthread 实现中,您可以使用“错误检查”互斥锁
  • 防止重入并确保为某些操作获取锁的正确方法是什么?(What is the correct way to prevent reentrancy and ensure a lock is acquired for certain operations?)
    问题 我正在设计一个基类,当它被继承时,将针对多线程环境中的上下文提供业务功能。 每个实例都可能有长时间运行的初始化操作,所以我想让对象可以重用。 为此,我需要能够: 为这些对象之一分配上下文以允许它完成其工作防止对象在已有上下文时被分配新上下文防止在对象没有上下文时访问某些成员 此外,每个上下文对象可以被许多工作对象共享。 是否有适合我正在尝试做的正确同步原语? 这是我想出的最适合我需要的模式: private Context currentContext; internal void BeginProcess(Context currentContext) { // attempt to acquire a lock; throw if the lock is already acquired, // otherwise store the current context in the instance field } internal void EndProcess() { // release the lock and set the instance field to null } private void ThrowIfNotProcessing() { // throw if this method is called while there is no lock
  • FIFO 信号量测试(FIFO semaphore test)
    问题 我已经实现了 FIFO 信号量,但现在我需要一种方法来测试/证明它们是否正常工作。 一个简单的测试是创建一些尝试等待信号量的线程,然后打印带有数字的消息,如果数字是有序的,它应该是 FIFO,但这还不足以证明这一点,因为该顺序可能有偶然发生。 因此,我需要一种更好的方法来测试它。 如果需要,也可以使用锁或条件变量。 谢谢 回答1 你用你的句子描述的“但这不足以证明它,因为该命令可能是偶然发生的”在某种程度上是一个已知的困境。 1) 即使您有规范,也无法确保该规范符合您的意图。 为了说明这一点,我将从“正确性的极限”中举一个例子。 让我们考虑一个分解函数的规范,它是: 计算 A 和 B,例如 A *​​ B = C 但这还不够,因为您可以有一个返回A=1和B=C 。 添加A,B != 1仍然可以导致A=-1和B=-C ,因此唯一正确的规范必须说明A,B>1 。 这只是为了说明编写符合真实意图的规范是多么复杂。 2)即使证明了一种算法,仍然不意味着在实践中实现是正确的。 唐纳德·克努斯 (Donald Knuth) 的这句话最能说明这一点: 注意上面代码中的错误; 我只是证明它是正确的,没有尝试过。 3)测试只能揭示错误的存在,而不是它们的不存在。 这句话可以追溯到 Dijkstra: 测试可用于显示错误的存在,但绝不能显示它们不存在。 结论:您注定要失败,您永远无法 100%
  • 什么是信号量?(What is a semaphore?)
    问题 信号量是一种编程概念,经常用于解决多线程问题。 我对社区的问题: 什么是信号量,如何使用? 回答1 可以将信号量视为夜总会的蹦蹦跳跳。 一次有大量的人员被允许进入俱乐部。 如果俱乐部已满,则不允许任何人进入,但一旦一个人离开,另一个人可能会进入。 这只是限制特定资源的使用者数量的一种方法。 例如,限制同时调用应用程序中的数据库的次数。 这是C#中非常教学法的示例:-) using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace TheNightclub { public class Program { public static Semaphore Bouncer { get; set; } public static void Main(string[] args) { // Create the semaphore with 3 slots, where 3 are available. Bouncer = new Semaphore(3, 3); // Open the nightclub. OpenNightclub(); } public static void OpenNightclub() { for (int i = 1
  • 如何更快地将视图渲染为图像?(How to render view into image faster?)
    问题 我正在制作放大镜应用程序,该程序允许用户触摸屏幕并移动手指,手指路径会出现一个放大镜。 我用截图来实现它,并将图像分配给放大镜图像视图,如下所示: CGSize imageSize = frame.size; UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0.0); CGContextRef c = UIGraphicsGetCurrentContext(); CGContextScaleCTM(c, scaleFactor, scaleFactor); CGContextConcatCTM(c, CGAffineTransformMakeTranslation(-frame.origin.x, -frame.origin.y)); [self.layer renderInContext:c]; UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return screenshot; 问题是self.layer renderInContext速度很慢,因此用户在移动手指时会感觉不流畅。 并且我尝试在其他线程中运行self.layer renderInContext ,但是
  • 可移植地处理 C++ 中的异常错误(Portably handle exceptional errors in C++)
    问题 我正在将 Visual C++ 应用程序移植到 GCC(应该在 MingW 和 Linux 上构建)。 现有代码在一些地方使用__try { ... } __except(1) { ... }块,因此几乎没有任何东西(可能是内存不足类型错误?)会使程序退出而不做一些最小的日志记录。 用 GCC 做类似的事情有哪些选择? 编辑:感谢在 Visual Studio 中指向 /EH 选项的指针,我现在需要的是一些有关如何在 Linux 上处理信号的示例。 我从 2002 年发现了这条消息。 除了SIGFPE和SIGSEVG之外,我还应该注意哪些其他信号? (主要关心那些可能因为我做错事而引起的) 赏金信息:我希望我的应用程序能够在退出之前自行记录尽可能多的错误情况。 我可能会收到哪些信号,并且在之后通常不可能记录错误消息? (内存不足,还有什么?) 我如何以可移植的方式处理异常和(最重要的)信号,使代码至少在 Linux 和 MingW 上工作相同。 #ifdef 没问题。 我不只是有一个记录失败的包装过程的原因是出于性能原因,我将一些数据保存到最后一分钟,所以如果出现问题,我想尽一切可能的尝试在之前写出数据退出。 回答1 try { xxx } catch(...) { xxx } 会更便携,但可能不会捕获那么多。 这取决于编译器设置和环境。 使用默认的 VC++ 设置,异步
  • 我如何等待异步调度的块完成?(How do I wait for an asynchronously dispatched block to finish?)
    问题 我正在测试一些使用Grand Central Dispatch进行异步处理的代码。 测试代码如下所示: [object runSomeLongOperationAndDo:^{ STAssert… }]; 测试必须等待操作完成。 我当前的解决方案如下所示: __block BOOL finished = NO; [object runSomeLongOperationAndDo:^{ STAssert… finished = YES; }]; while (!finished); 哪个看起来有些粗糙,您知道更好的方法吗? 我可以公开队列,然后通过调用dispatch_sync进行阻止: [object runSomeLongOperationAndDo:^{ STAssert… }]; dispatch_sync(object.queue, ^{}); …但这可能会使该object暴露过多。 回答1 尝试使用dispatch_semaphore 。 它看起来应该像这样: dispatch_semaphore_t sema = dispatch_semaphore_create(0); [object runSomeLongOperationAndDo:^{ STAssert… dispatch_semaphore_signal(sema); }]; if (
  • 有没有办法捕捉或处理EXC_BAD_ACCESS?(Is there a way to catch or handle EXC_BAD_ACCESS?)
    问题 据我了解,当您尝试访问错误的内存时会发生EXC_BAD_ACCESS(如果我输入错了,可以随时纠正我)? 有没有一种方法可以像在Java中的try-catch中那样捕获它,以防止应用程序完全失败? 回答1 不; EXC_BAD_ACCESS意味着事情已经脱离了EXC_BAD_ACCESS 。 您的程序正在尝试访问无效的内存地址。 即内存已损坏,并且没有可预测的恢复。 这可能是内存管理问题。 如果您可以重现该问题,请打开NSZombies,然后看看会发生什么。 或在此处发布回溯。 注意,try-catch样式异常在iOS / Cocoa中也是不可恢复的。 异常不可用于可恢复的错误处理。 那就是NSError的目的。 回答2 新的C库SignalRecovery可以使程序从操作系统异常(例如EXC_BAD_ACCESS 。 可以在IOS/MacOS/Linux 。 样例代码: signal_try(label) { // Add your code need try. int* ptr = NULL; *ptr = 0; } signal_catch(label) { // Add your code to process exceptions, or do nothing. siginfo_t* info = signal_info(); } signal_end(label)
  • 为 Cassandra Writes 获得背压的最佳方法是什么?(What is the best way to get backpressure for Cassandra Writes?)
    问题 我有一个服务,它以我控制的速度消耗队列中的消息。 我做了一些处理,然后尝试通过 Datastax Java 客户端写入 Cassandra 集群。 我已经使用maxRequestsPerConnection和maxConnectionsPerHost设置了我的 Cassandra 集群。 但是,在测试中我发现当我达到maxConnectionsPerHost和maxRequestsPerConnection对session.executeAsync调用不会阻塞。 我现在正在做的是使用一个new Semaphore(maxConnectionsPerHost * maxRequestsPerConnection)并在每个异步请求之前递增它,并在executeAsync返回的未来完成时递减它。 这工作得很好,但似乎是多余的,因为驱动程序已经在内部跟踪请求和连接。 有没有人想出更好的解决方案来解决这个问题? 一个警告:我希望请求在完成之前被视为未完成。 这包括重试! 我从集群中获得可重试失败的情况(例如等待一致性的超时)是我想要背压并停止使用队列中的消息的主要情况。 问题: // the rate at which I consume messages depends on how fast this method returns processMessage(message) {
  • 等待信号量的writeImageToSavedPhotosAlbum完成块(Wait for completion block of writeImageToSavedPhotosAlbum by semaphore)
    问题 在我的应用程序中,我用一个选择器打开相机,拍照后,我想通过以下方法保护资产库的安全。 调用writeImageToSavedPhotosAlbum之后,该方法将冻结。 没有信号灯,这些方法可以完美地工作。 但是比我想念的要更多的资产URL。 + (NSURL*)safeImageToAssetsLibrary:(UIImage *)image metadata:(NSDictionary *)metadata { ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; __block NSURL *retAssestURL = nil; dispatch_semaphore_t semaWaitingForSafeImage = dispatch_semaphore_create(0); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // safe the image to the assests library NSLog(@"Safe image to asssets library..."); dispatch_async(queue, ^{ [library
  • 在 C# 中验证 URL 的方法比 try-catch 更好吗?(A better way to validate URL in C# than try-catch?)
    问题 我正在构建一个应用程序来从互联网检索图像。 尽管它工作正常,但在应用程序中使用 try-catch 语句时它很慢(在错误的给定 URL 上)。 (1) 这是验证 URL 和处理错误输入的最佳方法 - 还是应该使用 Regex(或其他方法)? (2) 为什么我在textBox 中没有指定http:// 应用程序会尝试在本地查找图像? private void btnGetImage_Click(object sender, EventArgs e) { String url = tbxImageURL.Text; byte[] imageData = new byte[1]; using (WebClient client = new WebClient()) { try { imageData = client.DownloadData(url); using (MemoryStream ms = new MemoryStream(imageData)) { try { Image image = Image.FromStream(ms); pbxUrlImage.Image = image; } catch (ArgumentException) { MessageBox.Show("Specified image URL had no match", "Image Not